explain
SELECT COUNT(*) AS Count, CreatedBy
FROM `Notes`
INNER JOIN Users ON UserID = CreatedBy
INNER JOIN UserRoles ON URoleID = RoleID AND RoleID = 1
WHERE NoteVisible = 1 AND NoteText NOT LIKE '%SOME KEYWORD%'
AND Created BETWEEN '2014-02-24 00:00:00' AND '2014-02-24 23:59:59'
GROUP BY CreatedBy
如您所见参考为NULL并且通过 23 行而不是仅通过 1 行。现在对于这个例子来说这很快但是当我执行1-2个月的范围时,行变为> 10000 并且它会减慢页面的速度并锁定表格。
注意如果我删除了 00:00:00 和 23:59:59 ,那么它会使用索引只会通过1行但我需要从 00:00 开始选择所有数据,然后在 23:59 结束。
请帮我重新构建此查询以解决此问题或建议任何可能的解决方案。谢谢。
修改
用< 或> 或< = 或> =替换 BETWEEN 无法解决问题
答案 0 :(得分:4)
此查询使用索引
选择类型为range
,使用的密钥为Created
对于范围类型,ref
列始终为空,
参考文档:http://dev.mysql.com/doc/refman/5.7/en/explain-output.html#jointype_range
<强>范围强>
仅检索给定范围内的行,使用索引选择行。输出行中的键列指示使用哪个索引。 key_len包含使用的最长的关键部分。 此类型的ref列为NULL。
(强调我的)
答案 1 :(得分:0)
当您将datetime字段与greater_than / less_than比较中的字符串进行比较时。如果您使用强制转换或函数(如UNIX_TIMESTAMP())并将其他日期转换为unixtimestamp,那将会解决问题,但会破坏索引的使用。也许更好的解决方案是将日期作为unix时间戳存储在表中并在其上放置索引。
另一方面,你可以为你的sql添加“限制”也为我工作