我的 select 查询非常慢,我需要了解如何改进它
My select query is very slow, I need insights on how to improve it
我有一个用于检索 table 数据的查询。当返回超过3-4行时,查询很慢,我不明白为什么。
这是我的查询:
select
ig.id,
ig.username,
ig.created,
ig.is_completed,
ig.user_id,
ig.is_error,
ig.last_appeal_process_update,
(unix_timestamp() - ig.created) as time_running,
ig.is_deleted,
ap.id as appealprocessid,
(case
when ap.id is null then 0
when ap.id is not null then ap.status
end
) as current_status,
( select count(*) from appeal_process where ig_account_id = ig.id)
as total_appeals
from instagram_accounts ig
left join appeal_process ap on ig.id = ap.ig_account_id
where
(ig.username like CONCAT('%',?,'%') or ig.id like CONCAT('%',?,'%') or ig.username like CONCAT('%',?,'%')) and
ig.user_id = ? and is_deleted = 0 and
(
ap.id is null or
ap.id = ( -- WE SELECT ONLY THE LATEST APPEAL PROCESS
select max(id) from appeal_process tmp where tmp.ig_account_id = ig.id limit 1
)
)
order by ig.username asc
limit ?,?
编辑
这是 EXPLAIN 查询(虽然我不知道如何阅读它)
enter image description here
这是 为 instagram_accounts
显示创建 TABLE:
enter image description here
这是 为 appeal_process
显示创建 TABLE:
enter image description here
你的问题很可能是索引不足,需要对WHERE
AND JOIN
子句中使用的字段进行索引
为以下每个字段创建一个索引:
ig_account_id
ig.id
ig.username
is_deleted
ig.user_id
tmp.ig_account_id
在 instagram_accounts
上,您有特定于 user_id
、is_deleted
以及 username
的标准。由于您还按用户名排序,第一个解决方法是添加索引。
CREATE INDEX user_id_deleted_username ON
instagram_accounts(user_id, is_deleted, username);
在 appeal_process
中,您在 JOIN
和 tmp
子查询中都按 ig_account_id
进行搜索:
CREATE INDEX id_account_id ON
appeal_process ( ig_account_id)
在查询中,您正在提取用户最大申诉流程 ID 的状态。让 GROUP BY ig.id
简化如何获得结果,因为 MAX
和其他人是每组(为了强调而改变 CAP):
select
ig.id,
ig.username,
ig.created,
ig.is_completed,
ig.user_id,
ig.is_error,
ig.last_appeal_process_update,
(unix_timestamp() - ig.created) as time_running,
ig.is_deleted,
COALESE(MAX(ap.id),0) as appealprocessid,
(SELECT status FROM appeal_process WHERE appeal_process.id = appealprocessid LIMIT 1) as current_status,
COUNT(*) as total_appeals
from instagram_accounts ig
left join appeal_process ap on ig.id = ap.ig_account_id
where
(ig.username like CONCAT('%',?,'%') or ig.id like CONCAT('%',?,'%') or ig.username like CONCAT('%',?,'%')) and
ig.user_id = ? and is_deleted = 0
GROUP BY ig.id
order by ig.username asc
limit ?,?
我有一个用于检索 table 数据的查询。当返回超过3-4行时,查询很慢,我不明白为什么。
这是我的查询:
select
ig.id,
ig.username,
ig.created,
ig.is_completed,
ig.user_id,
ig.is_error,
ig.last_appeal_process_update,
(unix_timestamp() - ig.created) as time_running,
ig.is_deleted,
ap.id as appealprocessid,
(case
when ap.id is null then 0
when ap.id is not null then ap.status
end
) as current_status,
( select count(*) from appeal_process where ig_account_id = ig.id)
as total_appeals
from instagram_accounts ig
left join appeal_process ap on ig.id = ap.ig_account_id
where
(ig.username like CONCAT('%',?,'%') or ig.id like CONCAT('%',?,'%') or ig.username like CONCAT('%',?,'%')) and
ig.user_id = ? and is_deleted = 0 and
(
ap.id is null or
ap.id = ( -- WE SELECT ONLY THE LATEST APPEAL PROCESS
select max(id) from appeal_process tmp where tmp.ig_account_id = ig.id limit 1
)
)
order by ig.username asc
limit ?,?
编辑
这是 EXPLAIN 查询(虽然我不知道如何阅读它) enter image description here
这是 为 instagram_accounts
显示创建 TABLE:
enter image description here
这是 为 appeal_process
显示创建 TABLE:
enter image description here
你的问题很可能是索引不足,需要对WHERE
AND JOIN
子句中使用的字段进行索引
为以下每个字段创建一个索引:
ig_account_id
ig.id
ig.username
is_deleted
ig.user_id
tmp.ig_account_id
在 instagram_accounts
上,您有特定于 user_id
、is_deleted
以及 username
的标准。由于您还按用户名排序,第一个解决方法是添加索引。
CREATE INDEX user_id_deleted_username ON
instagram_accounts(user_id, is_deleted, username);
在 appeal_process
中,您在 JOIN
和 tmp
子查询中都按 ig_account_id
进行搜索:
CREATE INDEX id_account_id ON
appeal_process ( ig_account_id)
在查询中,您正在提取用户最大申诉流程 ID 的状态。让 GROUP BY ig.id
简化如何获得结果,因为 MAX
和其他人是每组(为了强调而改变 CAP):
select
ig.id,
ig.username,
ig.created,
ig.is_completed,
ig.user_id,
ig.is_error,
ig.last_appeal_process_update,
(unix_timestamp() - ig.created) as time_running,
ig.is_deleted,
COALESE(MAX(ap.id),0) as appealprocessid,
(SELECT status FROM appeal_process WHERE appeal_process.id = appealprocessid LIMIT 1) as current_status,
COUNT(*) as total_appeals
from instagram_accounts ig
left join appeal_process ap on ig.id = ap.ig_account_id
where
(ig.username like CONCAT('%',?,'%') or ig.id like CONCAT('%',?,'%') or ig.username like CONCAT('%',?,'%')) and
ig.user_id = ? and is_deleted = 0
GROUP BY ig.id
order by ig.username asc
limit ?,?