最初我有以下查询:
SELECT
rm.`routeNumber`
FROM
transactions tr
LEFT OUTER JOIN route_map rm
ON rm.`idStation` = tr.`idStation`
AND rm.`routeNumber` = CONCAT(
tr.`routeNumber`,
IF(
tr.`letterOfRoute` REGEXP '[0-9]+'
OR tr.`letterOfRoute` IS NULL,
'',
tr.`letterOfRoute`
)
)
LEFT OUTER JOIN station s
ON s.idStation = rm.`idStation`
WHERE tr.`operationType` = 2
AND tr.`routeNumber` != 0
AND tr.idStation != 0
AND tr.`idFiles` IN
(SELECT
fin.`idFiles`
FROM
files_in fin
WHERE fin.`idTerminal` LIKE 'V%')
AND rm.`routeNumber` IS NOT NULL
ORDER BY rm.`routeNumber`
此查询正常工作(至少有limit 1000
限制)。但是,当我尝试更改为仅输出非重复的rm.
routeNumber值时:
SELECT
DISTINCT rm.`routeNumber`
FROM
...
此查询开始起作用,似乎无限制地工作。瓶颈是transaction
表,因为该表包含大量数据(255679420行),并且缺少索引(例如,此表中查询的任何列上都没有索引,除了idFiles
)。我在idStation
列添加了索引,并按以下方式更改了查询:
SELECT rm_dist.`routeNumber`
FROM
(SELECT
DISTINCT rm.`routeNumber`, rm.`idStation`
FROM
route_map rm,
station s
WHERE rm.`routeNumber` IS NOT NULL
AND rm.`idStation` = s.idStation) rm_dist
WHERE EXISTS (
SELECT *
FROM transactions tr
WHERE tr.`operationType` = 2
AND tr.`routeNumber` != 0
AND tr.idStation != 0
AND tr.`idFiles` IN (SELECT fin.`idFiles` FROM files_in fin WHERE fin.`idTerminal` LIKE 'V%')
AND tr.`idStation` = rm_dist.`idStation`
AND rm_dist.`routeNumber` = CONCAT(
tr.`routeNumber`,
IF(tr.`letterOfRoute` REGEXP '[0-9]+' OR tr.`letterOfRoute` IS NULL,
'',
tr.`letterOfRoute`)
)
);
但没有改变。无论如何,查询似乎无限地工作,等待查询执行结束是没用的。有没有其他方法可以改善这个查询?
答案 0 :(得分:0)
尝试使用内部联接而不是IN子句,并避免使用无用的子选择
SELECT
DISTINCT rm.`routeNumber`
FROM
route_map rm,
station s
WHERE rm.`routeNumber` IS NOT NULL
AND rm.`idStation` = s.idStation
WHERE EXISTS (
SELECT *
FROM transactions tr
INNER JOIN (
SELECT fin.`idFiles` FROM files_in fin WHERE fin.`idTerminal` LIKE 'V%'
) T on tr.`idFiles` = t.`idFiles`
WHERE tr.`operationType` = 2
AND tr.`routeNumber` != 0
AND tr.idStation != 0
AND tr.`idStation` = rm.`idStation`
AND rm.`routeNumber` = CONCAT(
tr.`routeNumber`,
IF(tr.`letterOfRoute` REGEXP '[0-9]+' OR tr.`letterOfRoute` IS NULL,
'',
tr.`letterOfRoute`)
)
);