索引问题

时间:2010-12-25 15:04:04

标签: mysql

我有一个有3列的表:姓名,电话,日期。 我有3个索引:1个在电话上,1个在日期,1个在电话和日期。 我有以下声明:

SELECT * FROM(SELECT * FROM people WHERE phone IS NOT NULL ORDER BY date DESC)as t GROUP BY phone

基本上,我想获得按日期排序的所有唯一电话号码。这个表有大约250万行,但需要永远执行....我的索引是对的吗?

更新:

My EXPLAIN语句返回2行:1表用于主表,1表用于派生表。

它说我正在使用临时文件并使用filesort作为我的主表。

对于我的派生表,它说我可能的键是(电话)和(电话,日期),但它使用的是文件。

4 个答案:

答案 0 :(得分:1)

你不需要额外的select * from

SELECT distinct phone
FROM people 
WHERE phone IS NOT NULL 
ORDER BY phone, date DESC

更新 - 对于所有的专栏都试试这个:

SELECT name, date, distinct phone     
FROM people 
WHERE phone IS NOT NULL 
ORDER BY phone, date DESC

答案 1 :(得分:1)

我认为您的第三个索引是多余的,因为它应该已经被日期和电话列上的各个索引覆盖。

但是,在您的情况下,我不认为索引是查询速度慢的真正原因。相反,真正的问题可能是产生巨大临时数据集的内部查询,据我所知,MySql并没有真正针对此进行优化。

更新:
我认为以下查询应该具有与您相同的输出,但会避免内部选择:

SELECT phone, max(date) as maxDate 
FROM people 
WHERE phone IS NOT NULL 
GROUP BY phone
ORDER BY maxDate DESC

答案 2 :(得分:0)

如果您有一个索引(phone, date),则不需要索引(phone),因为MySQL可以轻松地使用第一个索引。

根据NULL phone个数量,索引无关紧要。你首先要求数据库服务器获取所有带有电话号码的元素,如果大多数人有一个电话号码,它将不关心索引,然后按日期对所有这些进行排序,而不是再次按电话和汇总排序,所以假设你的大多数条目有一个你要分拣两次的电话号码。

您可以在一个查询中轻松编写此内容:

SELECT * FROM people WHERE phone IS NOT NULL GROUP BY phone, date DESC

另见

的输出
EXPLAIN SELECT * FROM ( SELECT * FROM people WHERE phone IS NOT NULL ORDER BY date DESC) as t GROUP BY phone

VS

EXPLAIN SELECT * FROM people WHERE phone IS NOT NULL GROUP BY phone, date DESC

答案 3 :(得分:0)

我认为问题可能是“is not null”条款。使用此子句会导致db错过索引。它必须进行全表扫描以检查状况。考虑使用不同的默认值来表示null,以便您可以点击索引。