连接多个大表时如何进行更快的查询?

时间:2019-04-06 08:27:08

标签: mysql sql database

我有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;

当然,此语句可以正常工作,但是速度较慢。有没有更好的方法来编写此代码?

3 个答案:

答案 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子句开始,并首先使用这些列。然后从onselect子句中添加其他列。

hotelsbookings仅使用一列,因此这些索引很简单。

在没有OFFSET的情况下使用ORDER BY是非常可疑的。无论如何,结果集的顺序不确定,因此没有理由跳过名义上的“第一个”值。