所以我有一个560mb的数据库,最大的表500mb(超过1000万行)
我的查询需要加入5个表,大约需要10秒才能完成....
SELECT DISTINCT trips.tripid AS tripid,
stops.stopdescrption AS "perron",
Date_format(segments.segmentstart, "%H:%i") AS "time",
Date_format(trips.tripend, "%H:%i") AS "arrival",
Upper(routes.routepublicidentifier) AS "lijn",
plcend.placedescrption AS "destination"
FROM calendar
JOIN trips
ON calendar.vsid = trips.vsid
JOIN routes
ON routes.routeid = trips.routeid
JOIN places plcstart
ON plcstart.placeid = trips.placeidstart
JOIN places plcend
ON plcend.placeid = trips.placeidend
JOIN segments
ON segments.tripid = trips.tripid
JOIN stops
ON segments.stopid = stops.stopid
WHERE stops.stopid IN ( 43914, 23899, 23925, 23908,
23913, 19899, 23871, 43902,
23876, 25563, 18956, 19912,
23889, 23861, 23879, 23884,
23856, 19920, 19898, 23916,
23894, 20985, 23930, 20932,
20986, 22434, 20021, 19893,
19903, 19707, 19935 )
AND calendar.vscdate = Str_to_date('25-10-2011', "%e-%c-%Y")
AND segments.segmentstart >= Str_to_date('15:56', "%H:%i")
AND routes.routeservicetype = 0
AND segments.segmentstart > "00:00:00"
ORDER BY segments.segmentstart
我能做些什么来加快这个速度?任何提示都是受欢迎的,我对sql很新... 但我无法改变数据库的结构,因为它不是我的......
答案 0 :(得分:2)
使用EXPLAIN查找瓶颈:http://dev.mysql.com/doc/refman/5.0/en/explain.html 然后,也许,添加索引。
如果您不需要选择所有行,请使用LIMIT限制返回的结果计数。
答案 1 :(得分:1)
只是查看查询,我会说你应该确保在trips.vsid
,calendar.vscdate
,segments.segmentstart
和routes.routeservicetype
上有索引。我假设表中的所有主键都已有索引。
使用explain
作为Briedis建议将显示索引的工作情况。
您可能希望为某些表添加覆盖索引,例如trips.vsid
上包含tripid
和routeid
的索引。这样,数据库只能使用表中所需数据的索引,而不能从实际表中读取。
执行计划告诉您它成功地为除segments
表之外的所有内容使用索引,它在那里执行表扫描并按where
条件进行过滤。您应该尝试通过加入segments.segmentstart
和tripid
来为stopid
制作覆盖索引。
答案 2 :(得分:1)
尝试将群集索引添加到routes
和routeservicetype
上的routeid
表格。
根据routeservicetype
字段中数据的频率,您可以通过将联接中比较的数据量缩减到行程表来获得改进。
查看解释计划,您可能还想使用STRAIGHT_JOIN
而不是JOIN
(或INNER JOIN
)来强制使用表格的顺序,因为我已经拥有了用这种技术改进。
基本上,在查询开头放置提取数据的行数最小的表,最后的最大行计数表(在本例中可能是segments
表?),简单查找的例外(例如,用于描述)。
您还可以考虑更改WHERE
子句以过滤segments
上的stopid
表而不是stops
表,并在{{1}上创建聚簇索引表上(segments
,stopid
和tripid
) - 这个索引可以有效地满足两个连接和两个来自单个索引的子句......
构建索引......
segmentstart
改变了ALTER TABLE segments ADD INDEX idx_qry_helper ( stopid, tripid, segmentstart );
条款......
WHERE
在一天结束时,对于一个相当大的数据集上看似复杂的查询的10秒响应并不是那么糟糕!