MYSQL LEFT JOIN optimization with CASE

无人久伴 提交于 2019-12-12 13:46:39

问题


I spent some time trying to get working this SELECT with CASE but I failed... (thank to that I'm using COLASCE() now)

How could I optimize this SELECT by using CASE/IF sentences? Is this a fast way to query from different tables selected by a field?

SELECT a.folderid, a.foldername, a.contenttype, COALESCE(b.descriptor, c.descriptor, d.descriptor, e.descriptor, f.descriptor) as descriptor
FROM t_folders a
LEFT JOIN t_files b
ON a.contenttype = 'file' AND a.contentid = b.fileid
LEFT JOIN t_links c
ON a.contenttype = 'link' AND a.contentid = c.linkid
LEFT JOIN t_extfiles d
ON a.contenttype = 'extfile' AND a.contentid = d.extfileid
LEFT JOIN t_videos e
ON a.contenttype = 'video' AND a.contentid = e.videoid
LEFT JOIN t_exams f
ON a.contenttype = 'exam' AND a.contentid = f.examid
WHERE a.folderid = $folderId
ORDER BY a.folderid DESC

回答1:


Using case statement will not make the query faster in your case, but since you asked for it, below is how it would look like.

SELECT a.folderid, a.foldername, a.contenttype, 
    (CASE a.contenttype
        WHEN 'file' THEN b.descriptor
        WHEN 'link' THEN c.descriptor
        WHEN 'extfile' THEN d.descriptor
        WHEN 'video' THEN e.descriptor
        ELSE f.descriptor
    END CASE) AS descriptor
FROM t_folders a
LEFT JOIN t_files b ON a.contenttype = 'file' AND a.contentid = b.fileid
LEFT JOIN t_links c ON a.contenttype = 'link' AND a.contentid = c.linkid
LEFT JOIN t_extfiles d ON a.contenttype = 'extfile' AND a.contentid = d.extfileid
LEFT JOIN t_videos e ON a.contenttype = 'video' AND a.contentid = e.videoid
LEFT JOIN t_exams f ON a.contenttype = 'exam' AND a.contentid = f.examid
WHERE a.folderid = $folderId
ORDER BY a.folderid DESC

If each of the t_files, t_links, etc tables has the folder_id field, I would also try doing a UNION on these tables and then left join the result with t_folders to get the folderid and foldername.




回答2:


The joins have to be done this way because the come out of different tables. You cannot use CASE to switch which table a query is coming out of: the statement has to be parsed, including its data sources, before there are values to compare.

More to the point, CASE returns values, whereas table names are.. I don't know the technical term.. structural components of the query. It's sort of the same reason you can't select out of table "Cool_Stuff" with:

select * from "Cool_" + "Stuff"

Hope this answers your question!




回答3:


You may do the following

  select master.* ,  COALESCE(b.descriptor, c.descriptor, d.descriptor, e.descriptor,        f.descriptor) as descriptor
   from
   ( SELECT a.folderid, a.foldername, a.contenttype 

FROM t_folders a
WHERE a.folderid = $folderId
ORDER BY a.folderid DESC ) master
LEFT JOIN t_files b
ON master.contenttype = 'file' AND master.contentid = b.fileid
LEFT JOIN t_links c
ON master.contenttype = 'link' AND master.contentid = c.linkid
 LEFT JOIN t_extfiles d
 ON master.contenttype = 'extfile' AND master.contentid = d.extfileid
 LEFT JOIN t_videos e
ON master.contenttype = 'video' AND master.contentid = e.videoid
LEFT JOIN t_exams f
ON master.contenttype = 'exam' AND master.contentid = f.examid

While minimizing the result on table a, the joins operation can be optmizsed



来源:https://stackoverflow.com/questions/9749986/mysql-left-join-optimization-with-case

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!