我使用view在mysql中有子查询和concat。通常,查询工作很快,但如果查询的子查询工作非常缓慢。
此代码运行迅速(大约1秒)
CREATE OR REPLACE VIEW ilceler AS (
SELECT I.id, I.modulid, I.id as icerikidsi,
MAX(IF(D.alanid=2,D.textkisa,NULL)) AS ilceadi,
MAX(IF(D.alanid=2,D.id,NULL)) AS ilceadi_i,
I.seo_description,
I.seo_h1,
I.seo_h2,
I.seo_h3,
I.seo_h4,
I.seo_imgalt,
I.seo_imgtitle,
I.seo_keywords,
I.seo_pagetitle,
I.seo_url,
I.seo_urltitle
FROM datalar as D LEFT JOIN icerikler as I ON D.icerikid=I.id WHERE D.modulid='3' GROUP BY D.icerikid ORDER BY sehiradi asc )
但是这段代码的工作非常缓慢(大约20秒)
CREATE OR REPLACE VIEW ilceler AS (
SELECT I.id, I.modulid, I.id as icerikidsi,
MAX(IF(D.alanid=2,D.textkisa,NULL)) AS ilceadi,
MAX(IF(D.alanid=2,D.id,NULL)) AS ilceadi_i,
( SELECT CONVERT ( GROUP_CONCAT(D2.id SEPARATOR ' ₋ ' ) USING UTF8 )FROM datalar as D1
LEFT JOIN datalar as D2 ON D1.iliskialanid=D2.id WHERE D1.modulid='3' AND D1.alanid='3' AND D1.icerikid=icerikidsi ) as sehiradi_a ,
( SELECT GROUP_CONCAT(iliskiid SEPARATOR ' ₋ ') FROM datalar WHERE alanid='3' AND modulid='3' AND icerikid=icerikidsi ) as sehiradi_i,
( SELECT GROUP_CONCAT(D2.textkisa SEPARATOR ' ₋ ' ) FROM datalar as D1 LEFT JOIN datalar as D2 ON D1.iliskialanid=D2.id
WHERE D1.modulid='3' AND D1.alanid='3' AND D1.icerikid=icerikidsi ) as sehiradi ,
I.seo_description,
I.seo_h1,
I.seo_h2,
I.seo_h3,
I.seo_h4,
I.seo_imgalt,
I.seo_imgtitle,
I.seo_keywords,
I.seo_pagetitle,
I.seo_url,
I.seo_urltitle
FROM datalar as D LEFT JOIN icerikler as I ON D.icerikid=I.id WHERE D.modulid='3' GROUP BY D.icerikid ORDER BY sehiradi asc )
为什么呢?我哪里弄错了? 我在等你的帮助。
答案 0 :(得分:1)
您的子查询依赖于select的值,因此需要为每个返回的行执行这3个子查询中的每一个。对于少量行,这不是问题,但是有很多行可以快速累加。
正常的解决方案是连接子查询(因此对所有行都进行一次,你只需加入结果)。
例如: -
SELECT I.id,
I.modulid,
I.id as icerikidsi,
MAX(IF(D.alanid=2,D.textkisa,NULL)) AS ilceadi,
MAX(IF(D.alanid=2,D.id,NULL)) AS ilceadi_i,
sub1.sehiradi_a ,
sub2.sehiradi_i,
sub1.sehiradi ,
I.seo_description,
I.seo_h1,
I.seo_h2,
I.seo_h3,
I.seo_h4,
I.seo_imgalt,
I.seo_imgtitle,
I.seo_keywords,
I.seo_pagetitle,
I.seo_url,
I.seo_urltitle
FROM datalar as D
LEFT JOIN icerikler as I ON D.icerikid=I.id
LEFT OUTER JOIN
(
SELECT D1.icerikid, CONVERT ( GROUP_CONCAT(D2.id SEPARATOR ' ₋ ' ) USING UTF8 ) AS sehiradi_a, GROUP_CONCAT(D2.textkisa SEPARATOR ' ₋ ' ) AS sehiradi
FROM datalar as D1
LEFT JOIN datalar as D2 ON D1.iliskialanid=D2.id
WHERE D1.modulid='3'
AND D1.alanid='3'
GROUP BY D1.icerikid
) sub1
ON sub1.icerikid = I.id
LEFT OUTER JOIN
(
SELECT icerikid, GROUP_CONCAT(iliskiid SEPARATOR ' ₋ ') AS sehiradi_i
FROM datalar
WHERE alanid='3'
AND modulid='3'
GROUP BY icerikid
) sub2
ON sub2.icerikid = I.id
WHERE D.modulid='3'
GROUP BY D.icerikid
ORDER BY sehiradi asc
或者根据您的实际数据库设计,您可以将其简化为
SELECT I.id,
I.modulid,
I.id as icerikidsi,
MAX(IF(D.alanid=2,D.textkisa,NULL)) AS ilceadi,
MAX(IF(D.alanid=2,D.id,NULL)) AS ilceadi_i,
sub1.sehiradi_a ,
sub1.sehiradi_i,
sub1.sehiradi ,
I.seo_description,
I.seo_h1,
I.seo_h2,
I.seo_h3,
I.seo_h4,
I.seo_imgalt,
I.seo_imgtitle,
I.seo_keywords,
I.seo_pagetitle,
I.seo_url,
I.seo_urltitle
FROM datalar as D
LEFT JOIN icerikler as I ON D.icerikid=I.id
LEFT OUTER JOIN
(
SELECT D1.icerikid,
CONVERT ( GROUP_CONCAT(D2.id SEPARATOR ' ₋ ' ) USING UTF8 ) AS sehiradi_a,
GROUP_CONCAT(D2.textkisa SEPARATOR ' ₋ ' ) AS sehiradi,
GROUP_CONCAT(DISTINCT D1.iliskiid SEPARATOR ' ₋ ') AS sehiradi_i
FROM datalar as D1
LEFT JOIN datalar as D2 ON D1.iliskialanid=D2.id
WHERE D1.modulid='3'
AND D1.alanid='3'
GROUP BY D1.icerikid
) sub1
ON sub1.icerikid = I.id
WHERE D.modulid='3'
GROUP BY D.icerikid
ORDER BY sehiradi asc
但是这里有一个小问题。在MySQL中,视图不能包含从子查询中获取数据的FROM。因此,要在视图中使用此语法,您需要将子查询拆分为自己的视图。然后你可以加入视图而不是子查询。