我有一个带有文本列的表,其中包含每个操作的描述和 GUID。每个 GUID 最多可以出现三行。
我得到了大约 1000 个 GUID 的列表,我需要找到包含这些 GUID 的每一行。
我当前的查询是:
SELECT *
FROM table_name
WHERE CURR_DAY BETWEEN TO_DATE('2023-08-26', 'yyyy-mm-dd') AND TO_DATE('2023-10-11', 'yyyy-mm-dd')
AND (
purpose LIKE '%c016a45d-1e81-472d-a161-79369f87d6a0%'
OR purpose LIKE '%7e5a1766-c26e-4050-8120-25160bbcf5fb%'
OR purpose LIKE '%983006d0-b156-4aee-9ef2-21846c7a5b79%'
OR purpose LIKE '%154e86ca-6436-41d9-8593-f47ed1167766%'
-- ... repeated for about 1080 GUIDs
)
问题是这个查询需要3个多小时才能执行。
有更有效的方法来执行此搜索吗?
嗯,在同一列中同时包含 GUID 和其他文本似乎……不是最佳设计。但数据库可能不是你这么设计的。
至于你的问题,创建一个临时表(或一个 cte?)并加入该表应该会更快。 但请记住,使用通配符的 like 语句可能会非常慢,特别是当有 1000 个 like 语句时。 但尝试一下这段代码,让我知道性能是否有所提高。
-- Create a global temporary table
CREATE GLOBAL TEMPORARY TABLE TEMP_GUID_LIST
(
Guid VARCHAR2(255)
) ON COMMIT DELETE ROWS;
DECLARE
BEGIN
-- Insert GUIDs into the temporary table
INSERT INTO TEMP_GUID_LIST (Guid) VALUES ('c016a45d-1e81-472d-a161-79369f87d6a0');
INSERT INTO TEMP_GUID_LIST (Guid) VALUES ('7e5a1766-c26e-4050-8120-25160bbcf5fb');
-- results
FOR r in (SELECT t.*
FROM YourTableName t
INNER JOIN TEMP_GUID_LIST g ON t.purpose LIKE '%' || g.Guid || '%'
WHERE CURR_DAY BETWEEN TO_DATE('2023-08-26', 'yyyy-mm-dd') AND TO_DATE('2023-10-11', 'yyyy-mm-dd'))
LOOP
END LOOP;
COMMIT; -- This will also clear the rows from the temporary table
END;