左连接需要很长的时间在150 000行
问题描述:
我有一些困难来完成任务。左连接需要很长的时间在150 000行
这里是orders
表中的一些数据:
+----+---------+
| id | bill_id |
+----+---------+
| 3 | 1 |
| 9 | 3 |
| 10 | 4 |
| 15 | 6 |
+----+---------+
这里是从bills
表中的一些数据:
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+----+
我想列出所有bills
是有关联的order
。
为了实现这一目标,我认为使用的LEFT JOIN
被挪用,所以我写了这个请求:
SELECT * FROM bills
LEFT JOIN orders
ON bills.id = orders.bill_id
WHERE orders.bill_id IS NULL;
我还以为我有以下结果:
+----------+-----------+----------------+
| bills.id | orders.id | orders.bill_id |
+----------+-----------+----------------+
| 2 | NULL | NULL |
| 5 | NULL | NULL |
+----------+-----------+----------------+
但是我无法完成请求,它已经运行超过5分钟而没有结果,我停止了请求,因为无论如何这都不是生产时间。
我的真实数据集有超过150 000 orders
和100 000 bills
。数据集是否太大?
我的请求在某处出错了吗?
非常感谢您的提示!
编辑:侧面说明,表中没有定义外键... *飞走了*
答
您所查询的是罚款。我会用表的别名在写它:
SELECT b.*
FROM bills b LEFT JOIN
orders o
ON b.id = o.bill_id
WHERE o.bill_id IS NULL;
你不从orders
需要NULL
列,大概。
你需要orders(bill_id)
索引:
create index idx_orders_billid on orders(bill_id);
答
通过你的where语句,我假设你在寻找有没有票据的订单。
如果是这种情况,您不需要按照定义不存在的方式加入账单表。
你会发现
SELECT * FROM orders
WHERE orders.bill_id IS NULL;
一个更好的执行查询。
编辑:
对不起,我错过了你的“我要列出所有不具有关联顺序的账单。”在阅读问题时。正如@戈登指出的那样,索引肯定会有所帮助。然而,如果改变方案是可行的,我宁愿有一个可为空的bill.order_id列而不是一个订单。bill_id,因为你不需要左连接,内连接就足以获得订单账单,因为它可以更快地查询你的其他假定需求。
我认为这将是解决方案...问题是,'订单'表实际上充满了'bill_id' = 0,我刚刚意识到数据库完全不健康......感谢您的回应,但我最后用一个hacky的PHP脚本... – Hammerbot
@Gordon Linoff只是想学习...这里使用表别名的目的是什么?这有助于优化吗? – watermelon
@watermelon。 。 。当查询有多个表时,我总是使用表别名。只有一张桌子时,只能省略它们,因为我可能很懒。 –