我的查询问题需要监控州仓库,输入,输出,债务,卸货......
查询:
SELECT CONCAT(ulaz.sifra, ' - ', ulaz.uredjaj) AS uredjaj,
COUNT(DISTINCT ulaz.mac) AS kolicinaUlaza,
COUNT(DISTINCT izlaz.mac) AS kolicinaIzlaza,
COUNT(DISTINCT povracaj.mac) AS kolicinaPovracaj,
COUNT(DISTINCT otpis.mac) AS kolicinaOtpis,
COUNT(DISTINCT razd.mac1) AS kolicinaRazd,
sifr.min_kolicina AS minimalnaKolicina
FROM ulaz_u AS ulaz
LEFT JOIN zaduzenje_u AS izlaz ON ulaz.mac = izlaz.mac
LEFT JOIN povracaj_u AS povracaj ON ulaz.mac = povracaj.mac
LEFT JOIN otpis AS otpis ON ulaz.mac = otpis.mac
LEFT JOIN razduzenje_u AS razd on ulaz.mac = razd.mac1
LEFT JOIN sifrarnik as sifr on ulaz.sifra = sifr.sifra
WHERE ulaz.mac is not NULL
OR izlaz.mac is not null
OR povracaj.mac is not null
OR otpis.mac is not null
OR razd.mac1 is not null
GROUP BY ulaz.sifra
数据库是Mysql
我的问题是如何加快查询的执行速度?
仓库:
谢谢
答案 0 :(得分:0)
如评论部分所述,您可以将select子句缩减为ulaz.mac IS NOT NULL
。原因是你希望保证至少有一个不是null。因此,当ulaz.mac不为null时,标准已满。当ulaz.mac为null时,则不符合您的连接条件,因此所有mac都将为null。
如果dbms没有检测到这种情况,这可以加快查询速度。如上所述减少标准,很明显必须读取ulaz的哪一部分(如果你甚至有一个索引,这可能会非常快)。当然,dbms仍然必须加入所有其他表。 Mac上的索引再次有用。
SELECT CONCAT(ulaz.sifra, ' - ', ulaz.uredjaj) AS uredjaj,
COUNT(DISTINCT ulaz.mac) AS kolicinaUlaza,
COUNT(DISTINCT izlaz.mac) AS kolicinaIzlaza,
COUNT(DISTINCT povracaj.mac) AS kolicinaPovracaj,
COUNT(DISTINCT otpis.mac) AS kolicinaOtpis,
COUNT(DISTINCT razd.mac1) AS kolicinaRazd,
sifr.min_kolicina AS minimalnaKolicina
FROM ulaz_u AS ulaz
LEFT JOIN zaduzenje_u AS izlaz ON ulaz.mac = izlaz.mac
LEFT JOIN povracaj_u AS povracaj ON ulaz.mac = povracaj.mac
LEFT JOIN otpis AS otpis ON ulaz.mac = otpis.mac
LEFT JOIN razduzenje_u AS razd ON ulaz.mac = razd.mac1
LEFT JOIN sifrarnik AS sifr ON ulaz.sifra = sifr.sifra
WHERE ulaz.mac IS NOT NULL
GROUP BY ulaz.sifra;
另一种方法是预先聚合。首先选择所有mac以查看它们存在于哪些表中。你不经常感兴趣,但只是对是或否。你用EXISTS来测试它,如果mac上有索引,它应该非常快。那么你需要来自ulaz的独特的sifra + mac。加入这些并总结存在计数器。
SELECT
CONCAT(ulaz.sifra, ' - ', ulaz.uredjaj) AS uredjaj,
COUNT(*) AS kolicinaUlaza,
SUM(macs.is_islaz) AS kolicinaIzlaza,
SUM(macs.is_povracaj) AS kolicinaPovracaj,
SUM(macs.is_otpis) AS kolicinaOtpis,
SUM(macs.is_razd) AS kolicinaRazd,
sifr.min_kolicina AS minimalnaKolicina
FROM
(
SELECT sifra, mac, uredjaj
FROM ulaz_u
WHERE mac IS NOT NULL
GROUP by sifra, mac
) AS ulaz
INNER JOIN
(
SELECT
ulaz_macs.mac,
CASE WHEN EXISTS (select * FROM zaduzenje_u AS izlaz WHERE ulaz_macs.mac = izlaz.mac) THEN 1 ELSE 0 END AS has_islaz,
CASE WHEN EXISTS (select * FROM povracaj_u AS povracaj WHERE ulaz_macs.mac = povracaj.mac) THEN 1 ELSE 0 END AS has_povracaj,
CASE WHEN EXISTS (select * FROM otpis AS otpis WHERE ulaz_macs.mac = otpis.mac) THEN 1 ELSE 0 END AS has_otpis,
CASE WHEN EXISTS (select * FROM razduzenje_u AS razd WHERE ulaz_macs.mac = razd.mac) THEN 1 ELSE 0 END AS has_razd
FROM (SELECT DISTINCT mac FROM ulaz_u) AS ulaz_macs
) AS macs ON macs.mac = ulaz.mac
LEFT JOIN sifrarnik AS sifr ON ulaz.sifra = sifr.sifra
GROUP BY ulaz.sifra;
这可能更快或更快。 MySQL以连接速度最快而闻名。但是,exists子句更接近我们正在寻找的东西,并且我们保存了许多连接及其大的中间结果。好吧,试试吧。