我有3张桌子。所有3个表都有大约200万行。每天输入10,000-100,000个新条目。完成下面的sql语句大约需要10秒钟。有没有办法使此sql语句更快?
SELECT customers.name
FROM customers
INNER JOIN hotels ON hotels.cus_id = customers.cus_id
INNER JOIN bookings ON bookings.book_id = customers.book_id
WHERE customers.gender = 0 AND
customers.cus_id = 3
LIMIT 25 OFFSET 1;
当然,此语句可以正常工作,但是速度较慢。有没有更好的方法来编写此代码?
答案 0 :(得分:0)
子查询无济于事,但是正确的索引可以提高性能,因此请确保您具有正确的索引
create index idx1 on customers(gender , cus_id,book_id, name )
create index idex2 on hotels(cus_id)
create index idex3 on hotels(book_id)
答案 1 :(得分:0)
所有数据库服务器都有一种优化引擎,可以确定如何最好地获取所需数据。使用简单的查询(例如您显示的select),将无法以任何方式大大提高SQL的性能。正如其他人所说,子查询将无济于事,因为子查询将被优化为与联接相同的计划。
减少列数,添加索引,并增强服务器(如果可以的话)。
考虑缓存。我不是mysql专家,但发现本文有趣且值得一读。 https://www.percona.com/blog/2011/04/04/mysql-caching-methods-and-tips/
请查看汇总表部分,并考虑是否合适。是不是每个酒店,客户和预订都需要实时更新,还是每小时可以将其插入到汇总表中?
答案 2 :(得分:0)
我很难相信这与一个实际问题有关。按照书面规定,我希望它会一遍又一遍地返回相同的客户名称。
我建议以下索引:
customers(cus_id, gender, book_id, name)
hotels(cus_id)
bookings(book_id)
bookings
没去旅馆真的很奇怪。
首先,这些索引涵盖了查询,因此不需要访问数据页。逻辑是从where
子句开始,并首先使用这些列。然后从on
和select
子句中添加其他列。
hotels
和bookings
仅使用一列,因此这些索引很简单。
在没有OFFSET
的情况下使用ORDER BY
是非常可疑的。无论如何,结果集的顺序不确定,因此没有理由跳过名义上的“第一个”值。