我有一个有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作为我的主表。
对于我的派生表,它说我可能的键是(电话)和(电话,日期),但它使用的是文件。
答案 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,以便您可以点击索引。