任何人都可以帮助我在php中优化这个mysql查询,最多需要100秒。
SELECT DISTINCT
A.X,
A.Y,
A.Z,
FROM TableAA AS A
INNER JOIN( TableBB AS B)
ON(A.X = B.X) OR (A.X = B.M)
WHERE B.N = '$input' OR
A.Y = '$input' OR
A.Z = '$input'
TableAA拥有100万名企业 TableBB拥有900万名企业
还有其他方法可以编写此查询吗?
编辑:
TableBB在N,X,Y之间的连接上具有PRIMARY索引。 和X,N,M上的索引
TableAA在X上有PRIMARY索引,在Y,Z上有索引
答案 0 :(得分:0)
您的查询(以我能更好理解的方式格式化)是:
SELECT DISTINCT A.X, A.Y, A.Z
FROM TableAA A INNER JOIN
TableBB B
ON A.X = B.X OR A.X = B.M
WHERE B.N = '$input' OR A.Y = '$input' OR A.Z = '$input';
由于所有or
子句,这对于优化来说很复杂。我的第一个倾向是使用两个连接而不是or
:
SELECT DISTINCT A.X, A.Y, A.Z
FROM TableAA A left outer JOIN
TableBB B
ON A.X = B.X and B.N = '$input' left outer join
TableBB b2
on A.X = B2.M and B2.N = '$input'
WHERE (B.N is not null or B2.N is not null) and (A.Y = '$input' OR A.Z = '$input')
这更复杂,但您现在可以在B(N, X)
和B(N, M)
上添加索引以方便处理。
处理or
上的A
条件也很复杂。您可以尝试使用两个索引:A(Y, X, Z)
和A(Z, X, Y)
,看看它们是否被使用。否则,您可以将其拆分为两个查询:
(SELECT A.X, A.Y, A.Z
FROM TableAA A left outer JOIN
TableBB B
ON A.X = B.X and B.N = '$input' left outer join
TableBB b2
on A.X = B2.M and B2.N = '$input'
WHERE (B.N is not null or B2.N is not null) and A.Y = '$input'
)
union
(SELECT A.X, A.Y, A.Z
FROM TableAA A left outer JOIN
TableBB B
ON A.X = B.X and B.N = '$input' left outer join
TableBB b2
on A.X = B2.M and B2.N = '$input'
WHERE (B.N is not null or B2.N is not null) and A.Z = '$input'
)
此版本应使用上述索引。当然,您需要检查explain
计划,看看是否真的如此。但这可能有助于优化。
如果有任何方法可以简化条件,使它们and
而不是or
,那么这种优化就更容易了。