2010-07-17 84 views
0

使用解释下面的查询显示使用索引上加入

SELECT cha.cid AS cid, 
     cha.data AS dl 
FROM cha, c_users 
WHERE uid = 808 
AND cha.cid = c_users.cid; 
  1. 它在cha
  2. 全扫描使用从c_users多列索引(ciduid)。

为什么不使用cha的主键索引,而是使用全表扫描。有没有更好的方法来优化查询/表。

编辑: cha.cid是我的主要关键。在下面的评论后添加。

+0

'cha.cid'是您的主键吗? – 2010-07-17 10:41:44

+0

是cha.cid是主键 – rampr 2010-07-17 11:16:01

+0

我发现将它拆分成两个查询并创建相应索引更好 – rampr 2010-08-17 10:14:09

回答

1

在正常的BTREE和(cid,uid)上的索引中,如果不指定cid并仅搜索uid,则需要扫描。 (uid,cid)(注意订单)的索引可能会有帮助。

这绝不是一个保证它会被使用,如果某个索引/连接最有可能需要使用某个大比例的索引,MySQL可以猜测完整扫描可能会更快(连续读取)等原因。如果使用密钥,您可以使用FORCE INDEX进行检查,而扫描实际上是否更快(在测试之前在测试服务器上禁用查询缓存)。

+0

与BTREE无关 - 覆盖索引需要按照定义的顺序匹配最左边的列。如果第一个不匹配,则不考虑索引。 – 2010-07-17 18:10:14

+0

我的不好之处在于它与标准的2整数空间索引技巧(RTREE)相混淆,这当然与手边的问题无关,只是一个个人脑袋,而且仍然需要两个整数都有某种边界。在我的防守中:这里很晚;) – Wrikken 2010-07-18 13:27:04

-1

难道......

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的评论)。

+1

语法是'FROM table1 INNER JOIN table2 ON ...',不带逗号 – knittl 2010-07-17 11:15:19

+0

谢谢knittl。我会按照你的建议编辑答案。 – 2010-07-17 11:33:20

0

为uid列创建索引。

当您询问关于性能的问题时,EXPLAIN和CREATE TABLE语句的输出使帮助者变得更容易。请在下次添加它们。

+0

我已经描述了EXPLAIN的输出。你需要更多信息吗? – rampr 2010-07-20 06:08:23

0

由于cha没有可用于此查询的covering index,因此它必须访问数据页以检索它所需的一些数据。根据表统计信息,优化器决定首次扫描索引然后跳转到数据页的IO时间比仅扫描表更差。