MariaDB性能问题与“Where IN”子句有关

时间:2015-12-18 10:50:31

标签: mysql sql mariadb

我的SQL代码出了问题。我们开发了一个在MySQL上运行的应用程序,它运行良好。所以我决定试试MariaDB并将其安装在开发机器上。在某个查询Stmt上,我有一个我不明白的性能问题。查询如下:

 SELECT SAMPLES.*, UNIX_TIMESTAMP(SAMPLES.SAMPLE_DATE) as TIMESTAMP,RAWS.VALUE, DATAKEYS.RAW_ID, DATAKEYS.DATA_KEY_VALUE, DATAKEYS.DATA_KEY_ID, KEYDEF.KEY_NAME, KEYDEF.LDD_ID 
FROM 
PDS.TABLE_SAMPLES SAMPLES 
RIGHT OUTER JOIN PDS.TABLE_RAW_VALUES RAWS ON SAMPLES.SAMPLE_ID = RAWS.SAMPLE_ID 
RIGHT OUTER JOIN PDS.TABLE_SAMPLE_DATA_KEYS DATAKEYS ON(DATAKEYS.RAW_ID = RAWS.RAW_ID AND DATAKEYS.SAMPLE_ID = SAMPLES.SAMPLE_ID) OR 
(DATAKEYS.RAW_ID = 0 AND DATAKEYS.SAMPLE_ID = SAMPLES.SAMPLE_ID) 
RIGHT OUTER JOIN PDS.TABLE_DATA_KEY_DEFINITION KEYDEF ON(DATAKEYS.DATA_KEY_ID = KEYDEF.DATA_KEY_ID) 
WHERE 
SAMPLES.SAMPLE_ID IN(1991331,1991637,1991941,2046105,2046411,2046717,2047023,2047635,2047941,2048247)
AND (SAMPLES.PARAMETER_ID = 9) 
GROUP BY DATAKEYS.DATA_KEY_ID, RAWS.RAW_ID, DATAKEYS.DATA_KEY_ID 
ORDER BY SAMPLES.SAMPLE_ID, DATAKEYS.RAW_ID;

只要我在“WHERE IN”条件中只有一个值,查询需要大约10毫秒才能执行。这与MySQL 5.6相同。 只要我在那里添加另一个值,查询时间就会增加到几分钟。在MySQL中,它提升得非常慢,查询显示在MySQL上大约需要150毫秒,而使用完全相同的数据集在新的MariaDB安装上大约需要140秒。

我不是SQL专家,您能否给我一些线索,如何优化查询以按预期运行?

2 个答案:

答案 0 :(得分:1)

right outer joinwhere子句转换为内部联接。所以,只需使用正确的join类型(我不确定这是否会影响查询的优化,但它可以):

SELECT SAMPLES.*, UNIX_TIMESTAMP(SAMPLES.SAMPLE_DATE) as TIMESTAMP,RAWS.VALUE, DATAKEYS.RAW_ID, DATAKEYS.DATA_KEY_VALUE, DATAKEYS.DATA_KEY_ID, KEYDEF.KEY_NAME, KEYDEF.LDD_ID 
FROM PDS.TABLE_SAMPLES SAMPLES JOIN
     PDS.TABLE_RAW_VALUES RAWS
     ON SAMPLES.SAMPLE_ID = RAWS.SAMPLE_ID JOIN
     PDS.TABLE_SAMPLE_DATA_KEYS DATAKEYS
     ON (DATAKEYS.RAW_ID = RAWS.RAW_ID AND DATAKEYS.SAMPLE_ID = SAMPLES.SAMPLE_ID) OR 
        (DATAKEYS.RAW_ID = 0 AND DATAKEYS.SAMPLE_ID = SAMPLES.SAMPLE_ID) JOIN
     PDS.TABLE_DATA_KEY_DEFINITION KEYDEF
     ON DATAKEYS.DATA_KEY_ID = KEYDEF.DATA_KEY_ID)
WHERE SAMPLES.SAMPLE_ID IN (1991331, 1991637, 1991941, 2046105, 2046411, 2046717, 2047023, 2047635, 2047941, 2048247) AND
      (SAMPLES.PARAMETER_ID = 9) 
GROUP BY DATAKEYS.DATA_KEY_ID, RAWS.RAW_ID, DATAKEYS.DATA_KEY_ID 
ORDER BY SAMPLES.SAMPLE_ID, DATAKEYS.RAW_ID;

接下来,此查询的最佳索引 - 无论IN中的值的数量是多少,都是复合索引PDS.TABLE_SAMPLES(PARAMETER_ID, SAMPLE_ID)。这会处理WHERE子句。

因为您的查询在某些情况下运行得很快,我假设其他表具有适当的连接索引。

答案 1 :(得分:0)

而不是运营商' IN'尝试使用'存在'并使用子查询 而不是使用sample_id' s。