让我们假设:Ruby on Rails的SQL优化
网络has_many
频道 网络has_many
昵称
通道has_many
消息 通道belongs_to
网络
昵称has_many
消息 昵称belongs_to
网络
附加LY:
频道has_many
昵称,:through => :messages
昵称has_many
通道,:through => :messages
我这里有这个方法记录消息。非常简单,它会初始化它并将其链接到所需的相关模型。
def log_msg(userinfo, target, message, type = nil, time = nil)
# methods not shown yet obvious
return unless chan = find_channel(target)
return unless nick = find_nickname(userinfo)
msg = Message.new(:message => message)
msg.created_at = time unless time.nil?
if !type.nil? && msg.respond_to?(type)
msg.send("#{type}=", true)
end
msg.channel = chan
msg.nickname = nick
msg.save
end
以下是上述代码生成的所有查询。
Channel Load (0.0ms) SELECT * FROM "channels" WHERE ("channels"."name" = '#main_chat') AND ("channels".network_id = 1) LIMIT 1←[0m
Nickname Load (0.0ms) SELECT * FROM "nicknames" WHERE ("nicknames"."nickname" = 'bob_saget') LIMIT 1
Channel Load (0.0ms) SELECT "channels".id FROM "channels" WHERE ("channels"."name" = '#main_chat' AND "channels".network_id = 1 AND "channels".id <> 1) LIMIT 1
Network Load (0.0ms) SELECT * FROM "networks" WHERE ("networks"."id" = 1)
Message Create (0.0ms) INSERT INTO "messages" ("message", "is_action", "channel_id", "is_part", "updated_at", "is_nick", "is_mode", "is_topic", "is_ban", "nickname_id", "is_init", "is_quit", "is_join", "is_kick", "created_at") VALUES(NULL, NULL, 1, NULL, '2009-09-01 20:21:47', NULL, NULL, NULL, NULL, 1, 't', NULL, NULL, NULL, '2009-09-01 20:21:47')
正如你可以看到它查询频道表两次。我只是好奇为什么会发生这种情况。当我第一次找到频道时,它正在做“SELECT *”。似乎没有必要再次查询它的ID,因为它已经是已知的。同样,它为什么还要查询网络表。这似乎也不需要,因为创建新消息记录时不需要任何网络相关。