【发布时间】:2014-10-21 17:37:00
【问题描述】:
我有一个相当大的表(~ 6 GB),我在这个查询中遇到了性能问题:
SELECT f.*,
TIME_FORMAT(f.scheme, '%H:%i') as scheme,
TIME_FORMAT(f.actual, '%H:%i') as actual,
DATE_FORMAT(f.flight_date, '%d-%m-%Y') as flight_date_formatted,
a.iata
FROM flights_database f
LEFT JOIN airports a ON f.airport = a.airportNameClean
WHERE f.flight_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 30 DAY)
AND DATE_ADD(CURDATE(), INTERVAL 2 DAY)
AND (f.flight_number LIKE 'New York%' OR f.airport LIKE 'New York%' OR f.airline LIKE 'New York%')
ORDER by f.flight_date DESC, f.flight_scheme DESC
LIMIT 50"
我使用过EXPLAIN 并发现了这些潜在问题
- 使用多个 LIKE 和 OR 让它使用一个范围(使用 WHERE)的记录,似乎会使其变慢
- f.flight_scheme DESC,添加时使用文件排序。删除后,不使用文件排序。
我在flight_date, flight_number, airport, airline, scheme 上有一个索引,它报告使用它。
但是这个查询仍然需要大约 30 秒,这太离谱了。
使用某种子查询来替换 OR 部分可能会有所帮助。但是,在运行子查询后,如何确定我实际需要搜索的搜索查询类型(例如,哪一列)。
感谢您的想法和提示。
【问题讨论】:
-
而不是 LIKE,而是根据位置 id 或某事获取所有可能的去纽约的 filght_number,然后执行 JOIN,其他列的类似操作。
-
如果您不能使用 FK 引用城市的系统并使用索引查找或直接 FK 值,那么类似于
'New York' IN (LEFT(f.flight_number,8), LEFT(f.airport,8), LEFT(f.airline,8))的结构可能会更好?
标签: mysql sql performance indexing