我有一个查询正在拉动许多表,但它很慢,我想改进它。
SELECT
ph.phone_call_id AS id,
ph.call_subject AS callSubject,
ac.account_name AS accountName,
ph.trigger_on AS triggerOn,
ph.isAppointment,
ph.status,
ind.name AS industry,
cc.call_code_name AS callCode,
ac.account_id FROM phone_calls AS ph
INNER JOIN accounts AS ac ON ph.account_id = ac.account_id
INNER JOIN industries AS ind ON ind.industry_id = ac.industry_id
INNER JOIN call_codes AS cc ON ph.call_code_id = cc.call_code_id
WHERE
ac.status = 1 AND
ph.status = 1 AND
ph.owner_id = 1 AND
ac.do_not_call = 0 AND
ph.trigger_on BETWEEN '2012-10-09 00:00:00' AND '2013-04-09 23:59:59'
LIMIT 0,25
请注意,phone_Calls表有大约450万条记录和约300,000条记录。
我现在有这样的索引
ph.trigger_on
ph.owner_id
ph.status
ac.status
ac.do_not_call
ac.account_id
这是我解释查询时得到的内容
答案 0 :(得分:1)
重要的是要记住,制作质量指数的列是具有高度唯一性的列。我不确定您的系统中有多少status
个值,但如果您的表中只有3个可能的状态,则它不是一个好的索引。
将索引放在对正在执行的连接操作至关重要的列上也会很有帮助。在这种情况下,ph.account_id
,ac.account_id
,ind.industry_id
,ac.industry_id
,ph.call_code_id
,ph.owner_id
和cc.call_code_id
看起来都是很好的索引候选者(如果它们不是索引)。请注意,如果您的任何表具有大量索引(超过五个),则可能会降低查询速度。此外,如果涉及的任何表在其上执行了大量写入或删除(与读取次数相当),那么对这些表进行大量索引是不明智的,因为每个索引文件在具有许多表的表上更频繁地重写在它们上面执行写操作。根据我的经验,索引是一种艺术形式而不是科学,因此您必须进行一些实验才能找到最适合您系统的方法。如果可能,离线实验,看看给出数据集的最佳效果。祝你好运。
答案 1 :(得分:0)
与其他人提到的一样,如果您的INDEX列都是0和1位,那么您不需要索引,并且id自动增量应该对主索引更好。我猜测phone_call_id是INT还是唯一的吗?这是一个自动增量字段吗?
MySQL在内部使用自动递增id索引,因此对于像这样的表,最好有它。
如果您使用SHOW CREATE TABLE帐户发布架构结构; SHOW CREATE TABLE phone_calls;我们可以为您提供更多帮助。
我会把数据库 - 因为它只有300k - 并在本地加载它,然后添加自动增量列,如果它不是phone_call_id,删除所有其他索引除了:phone_call_id,account_id,industry_id和call_code_id。
为了向您提供更多帮助,我需要知道其他表的结构是什么,尤其是行的宽度和行数。