我怎样才能加快查询速度?

时间:2011-10-26 09:30:17

标签: mysql

所以我有一个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很新... 但我无法改变数据库的结构,因为它不是我的......

3 个答案:

答案 0 :(得分:2)

使用EXPLAIN查找瓶颈:http://dev.mysql.com/doc/refman/5.0/en/explain.html 然后,也许,添加索引。

如果您不需要选择所有行,请使用LIMIT限制返回的结果计数。

答案 1 :(得分:1)

只是查看查询,我会说你应该确保在trips.vsidcalendar.vscdatesegments.segmentstartroutes.routeservicetype上有索引。我假设表中的所有主键都已有索引。

使用explain作为Briedis建议将显示索引的工作情况。

您可能希望为某些表添加覆盖索引,例如trips.vsid上包含tripidrouteid的索引。这样,数据库只能使用表中所需数据的索引,而不能从实际表中读取。

编辑:

执行计划告诉您它成功地为除segments表之外的所有内容使用索引,它在那里执行表扫描并按where条件进行过滤。您应该尝试通过加入segments.segmentstarttripid来为stopid制作覆盖索引。

答案 2 :(得分:1)

尝试将群集索引添加到routesrouteservicetype上的routeid表格。

根据routeservicetype字段中数据的频率,您可以通过将联接中比较的数据量缩减到行程表来获得改进。

查看解释计划,您可能还想使用STRAIGHT_JOIN而不是JOIN(或INNER JOIN)来强制使用表格的顺序,因为我已经拥有了用这种技术改进。

基本上,在查询开头放置提取数据的行数最小的表,最后的最大行计数表(在本例中可能是segments表?),简单查找的例外(例如,用于描述)。

您还可以考虑更改WHERE子句以过滤segments上的stopid表而不是stops表,并在{{1}上创建聚簇索引表上(segmentsstopidtripid) - 这个索引可以有效地满足两个连接和两个来自单个索引的子句......

构建索引......

segmentstart

改变了ALTER TABLE segments ADD INDEX idx_qry_helper ( stopid, tripid, segmentstart ); 条款......

WHERE

在一天结束时,对于一个相当大的数据集上看似复杂的查询的10秒响应并不是那么糟糕!