MySQL索引在多列

时间:2018-09-04 07:04:10

标签: mysql indexing sql-execution-plan

我有一个选择查询,需要在其中包括以下几列(表中几乎所有列):

SELECT  ANI,CALL_ID, DATE_TIME, ABANDON_RATE, CALL_TYPE, CAMPAIGN, CAMPAIGN_TYPE, CUSTOMER_NAME, DISPOSITION, DNIS, LIST_NAME, 
        SESSION_ID, SKILL, AGENT_EMAIL, AGENT_GROUP, THIRD_PARTY_TALK_TIME, AFTER_CALL_WORK_TIME, HOLD_TIME, CALL_TIME, HANDLE_TIME, IVR_TIME,
        MANUAL_TIME, TALK_TIME, QUEUE_WAIT_TIME, advertiserName, affiliateName, callerID, campaignName, ChargentSFA__Biling_Phone__c, CONTACT_CREATE_TIMESTAMP,
        CONTACT_ID, CONTACT_MODIFIED_TIMESTAMP, Date_Added, destinationPhoneNumber, leadsource, number1, salesforce_id, source, transactionID,
        IVR_PATH 
FROM call_data_report 
WHERE ANI= '123456' OR DNIS = '123456' 
ORDER BY DATE_TIME desc;

此查询执行时间过多(超过3分钟)。为了提高查询性能,我在where子句中使用的列上创建了索引,即ANI和DNIS。

create index ani_idx on call_data_report(ANI,DNIS)

但是,当我检查上述select查询的EXPLAIN的输出时,它向我显示它没有使用索引。是否因为所有这些列?我需要创建哪种类型的索引才能提高上述查询的性能。

注意:ANI和DNIS列中的值为NULL。

谢谢!

2 个答案:

答案 0 :(得分:3)

仅当您将测试与AND(而不是OR)结合使用时,复合索引才有用。当您处于OR条件时,它必须独立测试每一列,但是复合索引是一棵树,该树在与其相关的DNIS中包含ANI的所有值。因此,您应该为每列创建单独的索引。

MySQL通常也不擅长优化OR查询。如果将其拆分为两个与UNION组合的查询,可能会更好:

SELECT ...
FROM call_data_report
WHERE ANI = 123456
UNION
SELECT ...
FROM call_data_report
WHERE DNIS = 123456

答案 1 :(得分:0)

在您的情况下,您可以尝试使用两个单列索引..

create index ani_idx1 on call_data_report(ANI);

create index ani_idx2 on call_data_report(DNIS); 

因为使用OR或复合索引ani_idx DNIS的第二个键未使用..