我必须创建一个sql查询,该查询获取包含字符“|”的名字,中间名或姓的所有用户。所以我做了类似的事情:
SELECT two.id,
two.username,
one.firstname,
one.middlename,
one.lastname
FROM table_one one INNER JOIN table_two two ON two.id = one.id
WHERE one.firstname LIKE '%|%'
OR one.middlename LIKE '%|%'
OR one.lastname LIKE '%|%'
此查询在测试环境中运行良好,大约有一千个配置文件,但它在生产环境中超时,其中包含数十万个配置文件,如果不是接近一百万个。
我们正在运行DB2,版本8.2
答案 0 :(得分:2)
您可以尝试将搜索拆分为删除OR
,因为性能不佳而臭名昭着:
SELECT
two.id,
two.username,
one.firstname,
one.middlename,
one.lastname
FROM (
SELECT id, firstname, middlename, lastname
FROM table_one
WHERE one.firstname LIKE '%|%'
UNION
SELECT id, firstname, middlename, lastname
FROM table_one
WHERE one.middlename LIKE '%|%'
UNION
SELECT id, firstname, middlename, lastname
FROM table_one
WHERE one.lastname LIKE '%|%'
) one
INNER JOIN table_two two ON two.id = one.id
在每个名称列上都有一个索引,每个偶然将在单独的联合查询中使用。
UNION
上的使用可以方便地丢弃重复项,因此多个名称列包含管道字符的情况不会导致重复输出。
答案 1 :(得分:0)
尝试
SELECT two.id,
two.username,
one.firstname,
one.middlename,
one.lastname
FROM table_one one INNER JOIN table_two two ON two.id = one.id
WHERE POSITION('|',concat(one.firstname,one.middlename,one.lastname),OCTETS)>0
或
SELECT two.id,
two.username,
one.firstname,
one.middlename,
one.lastname
FROM table_one one INNER JOIN table_two two ON two.id = one.id
WHERE POSITION('|',one.firstname,OCTETS)+POSITION('|',one.middlename,OCTETS)+POSITION('|',one.lastname),OCTETS)>0