我正在尝试解决数据库查询的性能问题。当查询的 WHERE 子句中考虑 ad.entry_exit_ts 时,性能从 ~2.5s 变为 ~330+s。
我只是偶尔在 MySQL 中编写代码,所以我没有足够的知识来正确调试它。如果有人可以帮助甚至向我指出我应该阅读以理解问题的文档,我将不胜感激。
查询的版本如下。
对于上下文,“item_details”是一个连接多个表并检索entry_exit_ts 值的视图。该视图的性能通常为我提到的约 2.5 秒或更快。左连接本身对性能的影响也可以忽略不计,只有在检查entry_exit_ts以过滤数据时才会发生。还有创建和修改的时间字段,其数据类型与entry_exit_ts相同,但它们不会以任何方式导致性能下降。
编辑:尝试将查询格式化为更具可读性
SELECT * FROM (
SELECT
ad.id
, ad.entry_exit_ts
, CASE
WHEN sub.sub_id::text = ad.id::character varying::text
THEN 'true'::text
ELSE 'false'::text
END AS subscribed from item_details ad
LEFT JOIN (
SELECT cast(sue.entity_id as varchar) as sub_id
FROM proj_notification.subscription_user su
LEFT JOIN proj_notification.subscription_user_entity sue
ON cast(su.user_id as varchar)=cast('35bd1f2a-e523-2a26-cad6-35bd1f2a' as varchar)
AND cast(su.id as varchar)= cast(sue.subscription_user_id as varchar)
AND cast(su.tenant_id as varchar)=cast('5aaaaaa3-5acc-4b6f-aa19-5aaaaaa38' as varchar)
) as sub
ON sub.sub_id::text = ad.id::character varying::text
WHERE (ad.entry_exit_ts >= 1695078000000)
) e
WHERE e.tenant_id::text='5aaaaaa3-5acc-4b6f-aa19-5aaaaaa38'
您应该考虑更改缩进和格式化策略,以使您的查询更易于阅读,并且此问题更易于回答。
导致性能下降的 WHERE 子句位于子查询中,执行多次,也许每次都执行全表扫描(如果该字段没有索引)。
因此,除了向entry_exit_ts添加索引之外,您还应该尝试将该WHERE子句移到子查询之外并将其应用到最终结果集,假设这不会使您的结果无效...
SELECT *
FROM (
SELECT ad.id,
ad.entry_exit_ts,
CASE
WHEN sub.sub_id::text = ad.id::character VARYING::text THEN 'true'::text
ELSE 'false'::text
END AS subscribed
FROM item_details ad
LEFT JOIN
(
SELECT cast(sue.entity_id AS varchar) AS sub_id
FROM proj_notification.subscription_user su
LEFT JOIN proj_notification.subscription_user_entity sue
ON cast(su.user_id AS varchar)=cast('35bd1f2a-e523-2a26-cad6-35bd1f2a' AS varchar)
AND cast(su.id AS varchar)= cast(sue.subscription_user_id AS varchar)
AND cast(su.tenant_id AS varchar)=cast('5aaaaaa3-5acc-4b6f-aa19-5aaaaaa38' AS varchar)) AS sub
ON sub.sub_id::text = ad.id::character VARYING::text
) e
WHERE e.tenant_id::text='5aaaaaa3-5acc-4b6f-aa19-5aaaaaa38'
AND entry_exit_ts >= 1695078000000