优化多个OR查询

时间:2011-01-19 21:39:37

标签: postgresql sqlperformance sql-optimization

我有一个数据库表,我需要验证用户是否输入了相同或部分相同的信息。

这就是我的想法

数据库布局

rec_id (pk), user_id,
name, phone, address_1, address_2, zip, 
company, co_phone, co_address_1, co_address_2, co_zip, 
billing, bi_phone, bi_address_1, bi_address_2, bi_zip

查询

SELECT rec_id 
FROM tbl_name
WHERE user_id = '123456789'
OR '1112223333' IN (phone, co_phone, bi_phone)
OR 'John Doe' IN (name, business, billing)
OR '12345' IN (zip, co_zip, bi_zip)
OR '123 main street' IN (address_1, co_address_1, bi_address_1)
OR 'po box 123' IN (address_2, co_address_2, bi_address_2)

如果任何数据匹配(是的,那将是误报)我需要旧的rec_id。

想知道是否有更好的方法可以做到这一点?

由于

1 个答案:

答案 0 :(得分:2)

要使此查询运行良好,您需要为要测试的每个列分别设置索引。对于OR条件,所有列的组合索引都没有任何帮助(如果您有AND,则会有所帮助。)

但是,无论您添加哪些索引,我都会想象您的查询会导致全表扫描。您可能想尝试使用UNION而不是OR来查看是否会产生影响:

SELECT rec_id FROM tbl_name WHERE tax_id = '123456789'
UNION
SELECT rec_id FROM tbl_name WHERE phone = '1112223333'
UNION
SELECT rec_id FROM tbl_name WHERE co_phone = '1112223333'
UNION
SELECT rec_id FROM tbl_name WHERE bi_phone = '1112223333'
UNION
SELECT rec_id FROM tbl_name WHERE name = 'John Doe'
UNION
SELECT rec_id FROM tbl_name WHERE business = 'John Doe'
UNION
SELECT rec_id FROM tbl_name WHERE billing = 'John Doe'
UNION
-- etc...

像这样重写它的想法是现在每个子查询都能够使用索引(当然假设你已经添加了必要的索引)。