连接多个大表时如何进行更快的查询?
Posted
技术标签:
【中文标题】连接多个大表时如何进行更快的查询?【英文标题】:How to make a faster query when joining multiple huge tables? 【发布时间】:2019-08-28 01:21:41 【问题描述】:我有 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;
当然,这个语句可以正常工作,但是速度很慢。有没有更好的方法来编写这段代码?
【问题讨论】:
在两个表中添加索引并重试,按时跟踪或参考此 [***.com/questions/2955459/what-is-an-index-in-sql] @M.Hemant 子查询是否也有助于它变得更快? 我觉得“hotels”表有一个 cust_id 有点奇怪。期望在预订表中为客户提供索引 FK。 @LukStorms 这只是我想到的一个简单示例。这不是我的实际桌子(也不是关于酒店的)。我的实际表在需要的地方有适当的 FK 和 PK。我只是想让问题尽可能简单和最小化。这些列只是为了使问题最小化。EXPLAIN
的输出在哪里?你的innodb_buffer_pool_size
的价值是多少?你有多少内存?硬盘呢? HDD 的品牌/型号/IOPS/带宽是多少?这是 I/O 绑定查询的一个明显案例,基本前提是增加 mysql 可以利用的内存。使用EXPLAIN
查看优化器的作用以及是否可以索引字段以帮助查询。
【参考方案1】:
所有数据库服务器都有一种优化引擎,它将确定如何最好地获取您想要的数据。使用诸如您显示的 select 之类的简单查询,没有任何方法可以大大提高 SQL 的性能。正如其他人所说,子查询无济于事,因为它会被优化到与连接相同的计划中。
如果可以的话,减少列数、添加索引、加强服务器。
考虑缓存。我不是 mysql 专家,但发现这篇文章很有趣,值得一读。 https://www.percona.com/blog/2011/04/04/mysql-caching-methods-and-tips/
查看汇总表部分并考虑是否合适。是否需要及时了解每个酒店、客户和预订,或者将其插入到汇总表中,每小时一次就可以了?
【讨论】:
【参考方案2】:子查询无济于事,但适当的索引可以提高性能,因此请确保您拥有适当的索引
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)
【讨论】:
【参考方案3】:我很难相信这与实际问题有关。正如所写,我希望这会一遍又一遍地返回相同的客户名称。
我会推荐以下索引:
customers(cus_id, gender, book_id, name)
hotels(cus_id)
bookings(book_id)
bookings
不去酒店真的很奇怪。
首先,这些索引覆盖了查询,因此不需要访问数据页。逻辑是从where
子句开始并首先使用这些列。然后从 on
和 select
子句添加其他列。
hotels
和 bookings
仅使用一列,因此这些索引是微不足道的。
在没有ORDER BY
的情况下使用OFFSET
非常可疑。无论如何,结果集的顺序是不确定的,因此没有理由跳过名义上的“第一个”值。
【讨论】:
以上是关于连接多个大表时如何进行更快的查询?的主要内容,如果未能解决你的问题,请参考以下文章