使用随机组件优化和索引查询

时间:2015-07-24 01:02:43

标签: php mysql indexing

我在继承的代码中有以下查询:

SELECT  a.row2, a.row3
    FROM  table1 a
    JOIN  table2 b ON a.row1 = b.row1
    WHERE  b.row2 IN (
        SELECT  id
            FROM  table3
            WHERE  id IN ($table3_ids)
                     )
    ORDER BY  RAND(); 

[a.row1是table1的主键]

几个问题:

  • 是否有更有效的方法来构建此查询?

  • 我已经在table1上有一个索引(row1,row2,row4);为(row1,row2,row3)创建一个单独的索引是多余的,或者我应该用(row1,row2,row3,row4)上的索引替换前者?

  • 从另一端,我已经在table2上有一个索引(row1,row2,row3);因为看起来我需要table2中的索引(row1,row2)来优化这个查询,所以包含一个索引是多余的,只需从同一个表中的不同索引中排除单个元素

这是我不清楚查询引擎如何知道哪个索引合适的地方;当它解析查询时,它是否首先检查表中的匹配索引?

  • 最后(也许最简单的回答),我正在用这种语法添加索引:

    ALTER TABLE table_name ADD KEY(row1,row2,row3);

创建索引后,我会手动重命名每个索引。是否可以在命令中包含索引的名称?

非常感谢!

2 个答案:

答案 0 :(得分:1)

这是您的查询:

SELECT a.row2, a.row3
FROM table1 a JOIN
     table2 b
     ON a.row1 = b.row1
WHERE b.row2 IN (SELECT id FROM table3 WHERE id IN ($table3_ids)) 
ORDER BY RAND();

我认为最好的索引是:table2(row2, row1)table1(row1, row2, row3)以及table3(id)。您可以将row4添加到table1索引,但它并没有什么不同。另外,你把你的专栏命名为#34; row"真的很奇怪。 - 对我来说,这会导致认知失调。

实际上,除非您的查询中有拼写错误,否则您可以省略table3并执行以下操作:

WHERE b.row2 IN ($table3_ids)

请注意,in ($table3_ids)需要字符串替换。这不能参数化。这引入了SQL注入的危险。

如果你的结果集超过几百行,可能是几千行,那么order by将是重要的。如果是这种情况,您可能希望尝试不同的方法来获得所需的结果。

答案 1 :(得分:1)

Gordon回答的一些补充:

ALTER TABLE reference在语法中显示可选的index_name

IN ( SELECT ... )非常低效;把它变成JOIN

SELECT  a.row2, a.row3
    FROM  table1 a
    JOIN  table2 b ON a.row1 = b.row1
    JOIN  table3 c ON b.row2 = c.id
    WHERE  c.id IN ($table3_ids) )
    ORDER BY  RAND(); 

...或

SELECT  a.row2, a.row3
    FROM  table1 a
    JOIN  table2 b ON a.row1 = b.row1
    WHERE b.row2  IN ($table3_ids) )
    ORDER BY  RAND(); 

(需要c的可能原因:您正在过滤c中缺少的ID?)

ORDER BY RAND()代价高昂。除非您还有LIMIT

,否则它基本上无法优化