【发布时间】:2011-10-18 07:54:16
【问题描述】:
我使用 codeigniter 的会话类,可以选择将会话数据存储在数据库中。这是为每个用户请求运行以检索会话的选择查询示例:
SELECT *
FROM (`ci_sessions`)
WHERE `session_id` = 'f7fd61f08a229kdu3093130a3da17e14'
AND `user_agent` = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.'
这是user guide中定义的会话数据的表结构:
CREATE TABLE IF NOT EXISTS `ci_sessions` (
session_id varchar(40) DEFAULT '0' NOT NULL,
ip_address varchar(16) DEFAULT '0' NOT NULL,
user_agent varchar(50) NOT NULL,
last_activity int(10) unsigned DEFAULT 0 NOT NULL,
user_data text DEFAULT '' NOT NULL,
PRIMARY KEY (session_id)
);
我的理解是,每当您有一个旨在返回单个结果的查询时,最好使用 LIMIT 0, 1 以便当数据库引擎找到所需的行时它只是返回而不是继续扫描整个表更多比赛。因此,将这个查询写成这样会更有效吗:
SELECT *
FROM (`ci_sessions`)
WHERE `session_id` = 'f7fd61f08a229kdu3093130a3da17e14'
AND `user_agent` = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.'
LIMIT 0, 1
有什么理由没有这样写吗?
【问题讨论】:
-
如果你有多个匹配的行,这首先是一个很大的负面因素;)如果你的代码被设计为期望单行,这至少会引发一个致命错误
-
我自己对此感到好奇。查看 Session 类源代码后,我认为没有理由不使用 LIMIT 子句。他们也使用
row()来获取数据,它只返回 first 行... -
@Casey:确实,这似乎没有优化,即使 CI 使用游标获取。此外,如果只获取一个(且唯一的)行,则不需要使用 offset 参数,
LIMIT 1会做得很好并且应该更快(不确定它是否实际上更有效,但它会有意义)。 -
欢迎有根据地推测为什么在这种情况下不使用 LIMIT。我在 CI Core 或 Reactor bitbucket 问题中没有看到与此相关的任何内容,因此可能会给他们带来一些东西。如果确实没有理由不使用这种简单的单行优化。
-
现在,我当然没有受过良好的 SQL 或数据库性能方面的教育(阅读:noob),但
session_id是主键这一事实与LIMIT 1无关是优化?
标签: mysql codeigniter session-state php