使用解释下面的查询显示使用索引上加入
SELECT cha.cid AS cid,
cha.data AS dl
FROM cha, c_users
WHERE uid = 808
AND cha.cid = c_users.cid;
- 它在
cha
表 - 全扫描使用从
c_users
多列索引(cid
,uid
)。
为什么不使用cha
的主键索引,而是使用全表扫描。有没有更好的方法来优化查询/表。
编辑: cha.cid是我的主要关键。在下面的评论后添加。
使用解释下面的查询显示使用索引上加入
SELECT cha.cid AS cid,
cha.data AS dl
FROM cha, c_users
WHERE uid = 808
AND cha.cid = c_users.cid;
cha
表c_users
多列索引(cid
,uid
)。为什么不使用cha
的主键索引,而是使用全表扫描。有没有更好的方法来优化查询/表。
编辑: cha.cid是我的主要关键。在下面的评论后添加。
在正常的BTREE和(cid,uid)上的索引中,如果不指定cid并仅搜索uid,则需要扫描。 (uid,cid)(注意订单)的索引可能会有帮助。
这绝不是一个保证它会被使用,如果某个索引/连接最有可能需要使用某个大比例的索引,MySQL可以猜测完整扫描可能会更快(连续读取)等原因。如果使用密钥,您可以使用FORCE INDEX
进行检查,而扫描实际上是否更快(在测试之前在测试服务器上禁用查询缓存)。
与BTREE无关 - 覆盖索引需要按照定义的顺序匹配最左边的列。如果第一个不匹配,则不考虑索引。 – 2010-07-17 18:10:14
我的不好之处在于它与标准的2整数空间索引技巧(RTREE)相混淆,这当然与手边的问题无关,只是一个个人脑袋,而且仍然需要两个整数都有某种边界。在我的防守中:这里很晚;) – Wrikken 2010-07-18 13:27:04
难道......
SELECT cha.cid AS cid,
cha.data AS dl
FROM cha INNER JOIN c_users ON cha.cid = c_users.cid
WHERE uid = 808;
是更地道?
(编辑考虑knittl的评论)。
语法是'FROM table1 INNER JOIN table2 ON ...',不带逗号 – knittl 2010-07-17 11:15:19
谢谢knittl。我会按照你的建议编辑答案。 – 2010-07-17 11:33:20
为uid列创建索引。
当您询问关于性能的问题时,EXPLAIN和CREATE TABLE语句的输出使帮助者变得更容易。请在下次添加它们。
我已经描述了EXPLAIN的输出。你需要更多信息吗? – rampr 2010-07-20 06:08:23
由于cha
没有可用于此查询的covering index,因此它必须访问数据页以检索它所需的一些数据。根据表统计信息,优化器决定首次扫描索引然后跳转到数据页的IO时间比仅扫描表更差。
'cha.cid'是您的主键吗? – 2010-07-17 10:41:44
是cha.cid是主键 – rampr 2010-07-17 11:16:01
我发现将它拆分成两个查询并创建相应索引更好 – rampr 2010-08-17 10:14:09