Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql Codeigniter会话类w/数据库存储选项未优化?_Mysql_Codeigniter_Session State_Php - Fatal编程技术网

Mysql Codeigniter会话类w/数据库存储选项未优化?

Mysql Codeigniter会话类w/数据库存储选项未优化?,mysql,codeigniter,session-state,php,Mysql,Codeigniter,Session State,Php,我使用codeigniter的会话类,并选择将会话数据存储在数据库中。这是为检索会话的每个用户请求运行的select查询的一个示例: SELECT * FROM (`ci_sessions`) WHERE `session_id` = 'f7fd61f08a229kdu3093130a3da17e14' AND `user_agent` = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.' 以下是中定义的会话数据的表结构: 我的理解是,每

我使用codeigniter的会话类,并选择将会话数据存储在数据库中。这是为检索会话的每个用户请求运行的select查询的一个示例:

SELECT *
FROM (`ci_sessions`)
WHERE `session_id` = 'f7fd61f08a229kdu3093130a3da17e14'
AND `user_agent` = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.'
以下是中定义的会话数据的表结构:

我的理解是,每当您有一个要返回单个结果的查询时,最好使用限制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

是否有任何理由不这样写?

可能只有一行,与用户代理和会话id相匹配,因此无需限制选择的数量,因为它是唯一的一行

该问题已报告给Bitbucket上的Codeigniter反应堆开发人员,并被视为无效:

他们的答复:

session_id字段是主键,因此它将是唯一的行


因此,看起来这实际上不是一个优化,只是没有必要。

如果有多个匹配行,这首先是一个很大的负面影响;)如果您的代码被设计为期望单行代码对此感到好奇,那么这至少会抛出一个致命错误。在查看会话类源代码之后,我发现没有理由不使用LIMIT子句。他们也使用
row()
抓取数据,只返回第一行…@Casey:事实上,这似乎没有得到优化,即使CI使用游标抓取。此外,如果只获取一行(并且是唯一的),则不需要使用offset参数,
LIMIT 1
会做得很好,而且速度应该更快(不确定它是否真的更有效,但这是有意义的)。即使是关于为什么在这种情况下不使用该限制的有根据的推测也是受欢迎的。我在CI堆芯或反应堆比特桶问题中没有看到与此相关的任何内容,因此可能会给他们带来一些东西。如果真的没有理由不使用这种简单的单行优化,那么它将受到欢迎,但是
session\u id
是主键这一事实是否与
LIMIT 1
不是优化有关?回答不正确/不清楚:如果没有限制,将搜索整个表以查找与WHERE子句匹配的值。可能有数千条记录,因此这会影响性能。应该只有一行,即使由于某种原因有更多行,CI也只返回第一行。使用二进制搜索函数,您将避免搜索所有记录。线性搜索不是很快。我不知道你为什么这么担心,反正你也不会觉得有什么不同。但是,是的,如果你真的想改变现状,可以通过SQL进行双线性搜索。@Grigor,请参阅对这个问题的第一个回答:这可能是一个性能问题,原因是每个用户发起的每个页面请求都会执行这个查询。如果一个站点在任何给定时间都可能有数千个用户会话处于活动状态,那么DBMS在搜索会话表其余部分时所花费的额外时间将导致性能损失,而在该站点已经找到它要查找的会话后,看起来您是对的Grigor,我向开发团队报告了这一点,他们说这是不必要的,并引用了另一篇堆栈溢出帖子。我觉得这样比较舒服,谢谢你的来电——就我而言,这已经解决了。为我第一次评论中的傲慢语气道歉。不过,我希望听到比一行更好的解释。我仍然需要等待至少14个小时才能授予奖金,所以请随意添加一个,这样答案就可以是独立的。
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