Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何优化SQL查询?_Mysql_Sql_Sql Optimization - Fatal编程技术网

Mysql 如何优化SQL查询?

Mysql 如何优化SQL查询?,mysql,sql,sql-optimization,Mysql,Sql,Sql Optimization,当我将where子句替换为where a1.id IN($some\u account\u id)时,查询速度很快,但在用户id中查询速度很慢。我尝试使用子查询,但无法使其工作 表架构如下所示: SELECT * FROM account a1 LEFT JOIN account a2 ON a1.group_id>0 AND a2.app_id=0 AND a1.group_id=a2.group_id AND a1.id!=a2.id JOIN user_account_ref u

当我将where子句替换为
where a1.id IN($some\u account\u id)
时,查询速度很快,但在用户id中查询速度很慢。我尝试使用子查询,但无法使其工作

表架构如下所示:

SELECT *
FROM account a1 
LEFT JOIN account a2 ON a1.group_id>0 AND a2.app_id=0 AND a1.group_id=a2.group_id AND a1.id!=a2.id 
JOIN user_account_ref uar ON uar.account_id=a1.id OR (uar.account_id=a2.id AND uar.role>0) 
WHERE uar.user_id IN ($some_user_ids);
更多信息:

---account---
id
app_id
group_id

---user_account_ref---
id
user_id
account_id
role
速度快,结果中有4行

select * from user_account_ref where user_id IN (xxx)

也很快,结果中有2000多行。

请尝试这三个索引,看看它们是否解决了性能问题。(然后查看解释计划,看看哪些索引没有被使用,并删除它们。)

select * from user_account_ref where user_id IN (xxx)
idx1
用于加速您的
帐户
自加入
idx2
idx3
是提供给DBMS的两个选项,用于快速加入
user\u account\u ref
表。希望DBMS能够从中选择一个,从而更快地执行查询

如果这些索引没有帮助,您可以先尝试只删除
idx3
,以便强制执行
idx2
,因为用户的条件似乎大大减少了要查看的行,DBMS可能不知道这一点


最后,您可以更新MySQLs表统计信息,以便DBMS更好地了解您的表。祝你好运。

我终于使用了@Akina建议的联合查询。我在
组id
上添加了一个索引,由@Thorsten Kettner提醒。谢谢你们两位

以下是我的新查询:

create index idx1 on account (group_id, id, app_id);
create index idx2 on user_account_ref (user_id, account_id);
create index idx3 on user_account_ref (account_id, user_id);
如果速度很快:

SELECT a.id, uar.* 
FROM account a
JOIN user_account_ref uar ON uar.account_id=a.id AND uar.status=0
WHERE uar.user_id IN (xxx)

UNION

SELECT a.id, uar.* 
FROM account a,
(
    SELECT DISTINCT ra.id, ra.group_id
    FROM account ra
    JOIN user_account_ref uar ON ra.id=uar.account_id and ra.app_id=0
    WHERE uar.user_id in (xxx) AND ra.group_id>0
) ra
JOIN user_account_ref uar ON uar.role>0
WHERE a.group_id=ra.group_id AND uar.account_id=ra.id AND uar.user_id IN (xxx);

请阅读本文:-将您的查询分成两个单独的联合查询。
SELECT a1.*, a2.* 
FROM account a1 LEFT JOIN
     account a2
    ON a1.group_id > 0 AND 
       a2.app_id = 0 AND
       a1.group_id = a2.group_id AND
       a1.id <> a2.id;
    SELECT a1.*, a2.*, COALESCE(uar1.role, uar2.role) as role
    FROM account a1 LEFT JOIN
         account a2
         ON a1.group_id > 0 AND 
            a2.app_id = 0 AND
            a1.group_id = a2.group_id AND
            a1.id <> a2.id LEFT JOIN
         user_account_ref uar1 AND uar2.role > 0
         ON uar1.account_id = a1.id LEFT JOIN
         user_account_ref uar2
         ON uar2.account_id = a2.id AND uar2.role > 0
WHERE uar1.user_id IN ($some_user_ids) OR
      uar2.user_id IN ($some_user_ids) ;