前几天我的查询有问题。一个大型数据集大约需要 10 秒。查询看起来像这样:
SELECT a.* from Document as a
LEFT JOIN Waybill as b on a.waybill = b.id
WHERE a.enterpriseGuid = '763a3ac3-a3c7-4379-9735-2a4a96e87e5d'
OR b.enterpriseGuid = '763a3ac3-a3c7-4379-9735-2a4a96e87e5d'
这运行得很慢。但是,然后我将其更改为:
SELECT a.* from Document as a
LEFT JOIN Waybill as b on a.waybill = b.id
WHERE a.enterpriseGuid = '763a3ac3-a3c7-4379-9735-2a4a96e87e5d'
UNION ALL
SELECT a.* from Document as a
LEFT JOIN Waybill as b on a.waybill = b.id
WHERE b.enterpriseGuid = '763a3ac3-a3c7-4379-9735-2a4a96e87e5d'
这花了大约 0.01 秒,尽管这两个查询基本上产生了相同的结果!我查找了官方的 MySQL 文档,并在这里发现了一个有趣的评论:
在 OR 情况下使用索引会失去速度优势 (4.1.10):
SELECT * FROM a WHERE index1 = 'foo' UNION SELECT * FROM a WHERE index2 = 'baar';
比
SELECT * FROM a WHERE index1 = 'foo' OR index2 = 'bar';
所以,我的问题有 3 个部分:
- 在生产系统(即数据集非常大的地方)的选择查询中使用 OR 子句真的很糟糕吗?
- 这个 OR 查询可以通过索引以某种方式调整吗?现在,我用于过滤的查询中的两列实际上都已编入索引。我可以创建一些棘手的复合索引以使 OR 像 UNION ALL 一样快吗?
- 这是特定于供应商的问题,还是我在使用 Oracle 或 Postgresql 时会遇到同样的问题?