Ash*_*jar 0 mysql performance optimization query-performance
这是我的查询:
SELECT a.z_companyid_pk "z_companyid_pk" ,
a.company_name "Client" ,
a.display_name "Display_Name" ,
a.z_parentcompanyid_fk "Parent_Company",
a.z_resellerid_fk "Reseller" ,
(SELECT company_name
FROM company_mst
WHERE z_companyid_pk= a.z_resellerid_fk
)
"Reseller_name",
(SELECT IF(COUNT(*)>=1,"YES","NO")
FROM webprofile
WHERE z_boxid_fk IN
(SELECT z_boxid_pk
FROM box_mst
WHERE z_companyid_fk=a.z_companyid_pk
)
)
"V1_Website",
(SELECT IF(COUNT(*)>=1,"YES","NO")
FROM webapp_mst
WHERE z_companyid_fk=a.z_companyid_pk
)
"V2_Website",
(SELECT IF(COUNT(*)>0,"YES","NO")
FROM widget_mst
WHERE widget_status=1
AND type IN("templated-menu",
"menus")
AND z_companyid_fk=a.z_companyid_pk
)
"Widgets_with_my_menu",
(SELECT IF(COUNT(imagehtml)>0,"YES","NO")
FROM image_mst
WHERE LENGTH(imagehtml)>0
AND z_companyid_fk =a.z_companyid_pk
)
"HTML_menus",
(SELECT MAX(login_datetime)
FROM loginlog_mst a
LEFT OUTER JOIN contact_mst b
ON a.z_contactid_fk=b.z_contactid_pk
WHERE b.z_companyid_fk =a.z_companyid_pk
)
"LCI" ,
k.z_boxid_pk "DMB_Box_ID",
k.box_name ,
(SELECT box_lastcheck
FROM box_online
WHERE z_boxid_fk=k.z_boxid_pk
)
"LCI_last_Checked_in_Date",
(SELECT websitelink
FROM company_profile
WHERE z_companyid_fk=a.z_companyid_pk
)
"Website",
(SELECT company_email
FROM company_profile
WHERE z_companyid_fk=a.z_companyid_pk
)
"Primary_Contact_Email" ,
concat(a.company_address_line1,a.company_address_line2) "address",
(SELECT city_name
FROM city_mst
WHERE z_cityid_pk = a.z_cityid_fk
)
"city",
(SELECT state_name
FROM state_mst
WHERE z_stateid_pk = a.z_stateid_fk
)
"Province" ,
(SELECT country_name
FROM country_mst
WHERE z_countryid_pk=z_countryid_fk
)
"country_name" ,
a.company_postalcode "zip_postal_code",
(SELECT telephone
FROM company_profile
WHERE z_companyid_fk=a.z_companyid_pk
)
"company_telephone" ,
a.z_timezoneid_fk ,
b.timezone "time_Zone",
(SELECT facebooklink
FROM company_profile
WHERE z_companyid_fk=a.z_companyid_pk
)
"facebook",
(SELECT twitterlink
FROM company_profile
WHERE z_companyid_fk=a.z_companyid_pk
)
"twitter",
(SELECT bizurl
FROM user_settings us
INNER JOIN asset_mst am
ON (
us.userid=am.userid
)
WHERE us.isiteid =1
AND am.z_companyid_fk=a.z_companyid_pk
)
"Yelp",
(SELECT bizurl
FROM user_settings us
INNER JOIN asset_mst am
ON (
us.userid=am.userid
)
WHERE us.isiteid =2
AND am.z_companyid_fk=a.z_companyid_pk
)
"Urbanspoon",
(SELECT bizurl
FROM user_settings us
INNER JOIN asset_mst am
ON (
us.userid=am.userid
)
WHERE us.isiteid =3
AND am.z_companyid_fk=a.z_companyid_pk
)
"Trip_Advisor",
(SELECT bizurl
FROM user_settings us
INNER JOIN asset_mst am
ON (
us.userid=am.userid
)
WHERE us.isiteid =4
AND am.z_companyid_fk=a.z_companyid_pk
)
"Citysearch",
(SELECT bizurl
FROM user_settings us
INNER JOIN asset_mst am
ON (
us.userid=am.userid
)
WHERE us.isiteid =5
AND am.z_companyid_fk=a.z_companyid_pk
)
"Open_Table",
(SELECT bizurl
FROM user_settings us
INNER JOIN asset_mst am
ON (
us.userid=am.userid
)
WHERE us.isiteid =6
AND am.z_companyid_fk=a.z_companyid_pk
)
"ZAGAT",
(SELECT bizurl
FROM user_settings us
INNER JOIN asset_mst am
ON (
us.userid=am.userid
)
WHERE us.isiteid =32
AND am.z_companyid_fk=a.z_companyid_pk
)
"Zomato" ,
d.z_contactid_fk "Email_contact_ID",
d.username "Email_User_Name" ,
d.contact_firstname ,
d.contact_lastname ,
d.status ,
(SELECT MAX(login_datetime)
FROM loginlog_mst
WHERE z_contactid_fk=d.z_contactid_fk
)
"last_login_date",
(SELECT GROUP_CONCAT(groupname)
FROM contact_group_mst
WHERE z_companyid_fk=a.z_companyid_pk
)
"group_name"
FROM company_mst a
LEFT OUTER JOIN timezone_mst b
ON a.z_timezoneid_fk=b.z_timezoneid_pk
LEFT OUTER JOIN company_profile c
ON a.z_companyid_pk=c.z_companyid_fk
LEFT OUTER JOIN
(SELECT v.z_contactid_fk ,
v.z_companyid_fk ,
w.username ,
w.contact_firstname,
w.contact_lastname ,
IF(contact_wtaccess=1,"Veryfied","Not Veryfied") "status"
FROM priviledge_mst v
LEFT OUTER JOIN contact_mst w
ON v.z_contactid_fk=w.z_contactid_pk
WHERE w.type <>"Staff"
)
d
ON a.z_companyid_pk=d.z_companyid_fk
LEFT OUTER JOIN
(SELECT z_boxid_pk,
box_name ,
asset_mst.z_companyid_fk
FROM box_mst
INNER JOIN asset_mst
ON (
box_mst.userid_fk = asset_mst.userid
)
WHERE asset_mst.status = 0
AND type ="menubox"
)
k
ON a.z_companyid_pk=k.z_companyid_fk
WHERE a.status <> 0
AND a.z_companyid_pk IN(101089,104001,103863)
ORDER BY a.company_name;
Run Code Online (Sandbox Code Playgroud)
在我的远程 MySQL 服务器上执行此查询至少需要 1 分钟。由于我是 MySQL 的新手,我对优化查询不太了解,所以请通过建议一些技术或修改或我可以应用于此查询以提高性能的任何提示来帮助我。
And*_*y M 15
您的查询中至少有三个部分会或可能会从重写中受益:
SELECT 子句中的这五个相关子查询基于相同的条件从同一个表中检索数据:
(select websitelink from company_profile where z_companyid_fk=a.z_companyid_pk) "Website",
(select company_email from company_profile where z_companyid_fk=a.z_companyid_pk) "Primary_Contact_Email",
(select telephone from company_profile where z_companyid_fk=a.z_companyid_pk) "company_telephone",
(select facebooklink from company_profile where z_companyid_fk=a.z_companyid_pk) "facebook",
(select twitterlink from company_profile where z_companyid_fk=a.z_companyid_pk) "twitter",
Run Code Online (Sandbox Code Playgroud)
您可以通过company_profile
在主 FROM 子句中引入左连接并仅引用主 SELECT 中的列来重写它们。但是等等,你已经有了这样的连接:
LEFT OUTER JOIN company_profile c on a.z_companyid_pk=c.z_companyid_fk
Run Code Online (Sandbox Code Playgroud)
出于某种原因,您没有使用它。您可以通过像这样重写上面的五列来使用它:
c.websitelink AS "Website",
c.company_email AS "Primary_Contact_Email",
c.telephone AS "company_telephone",
c.facebooklink AS "facebook",
c.twitterlink AS "twitter",
Run Code Online (Sandbox Code Playgroud)
(AS
关键字是不必要的。我使用它是因为在我看来它提高了可读性,但您可以随意省略它。)
这一系列相关的子查询也从同一个行集中提取数据,但每个子查询都有一个额外的条件,这使得这与前一个不同:
(SELECT bizurl FROM user_settings us INNER JOIN asset_mst am ON (us.userid=am.userid) where us.isiteid=1 and am.z_companyid_fk=a.z_companyid_pk ) "Yelp",
(SELECT bizurl FROM user_settings us INNER JOIN asset_mst am ON (us.userid=am.userid) where us.isiteid=2 and am.z_companyid_fk=a.z_companyid_pk ) "Urbanspoon",
(SELECT bizurl FROM user_settings us INNER JOIN asset_mst am ON (us.userid=am.userid) where us.isiteid=3 and am.z_companyid_fk=a.z_companyid_pk ) "Trip_Advisor",
(SELECT bizurl FROM user_settings us INNER JOIN asset_mst am ON (us.userid=am.userid) where us.isiteid=4 and am.z_companyid_fk=a.z_companyid_pk ) "Citysearch",
(SELECT bizurl FROM user_settings us INNER JOIN asset_mst am ON (us.userid=am.userid) where us.isiteid=5 and am.z_companyid_fk=a.z_companyid_pk ) "Open_Table",
(SELECT bizurl FROM user_settings us INNER JOIN asset_mst am ON (us.userid=am.userid) where us.isiteid=6 and am.z_companyid_fk=a.z_companyid_pk ) "ZAGAT",
(SELECT bizurl FROM user_settings us INNER JOIN asset_mst am ON (us.userid=am.userid) where us.isiteid=32 and am.z_companyid_fk=a.z_companyid_pk ) "Zomato",
Run Code Online (Sandbox Code Playgroud)
重写这些将需要的不仅仅是和外连接以保持相同的输出格式。
首先这个加入
user_settings us INNER JOIN asset_mst am ON (us.userid=am.userid)
Run Code Online (Sandbox Code Playgroud)
可能返回这样的数据:
... am.z_companyid_fk us.isiteid us.bizurl ...
--- -------------- ---------- ----------------------- ---
... some_comp_id 1 some-Yelp-URL ...
... some_comp_id 2 some-Urbanspoon-URL-URL ...
... some_comp_id 3 some-Trip_Advisor-URL ...
... some_comp_id 4 some-Citysearch-URL ...
... some_comp_id 5 some-Open_Table-URL ...
... some_comp_id 6 some-ZAGAT-URL ...
... some_comp_id 32 some-Zomato-URL ...
... ... ... ... ...
Run Code Online (Sandbox Code Playgroud)
但是您希望它们排成一行,如下所示:
... am.z_companyid_fk Yelp Urbanspoon Trip_Advisor Citysearch Open_Table ZAGAT Zomato
--- ----------------- ------------- ----------------------- --------------------- ------------------- ------------------ -------------- ---------------
... some_comp_id some-Yelp-URL some-Urbanspoon-URL-URL some-Trip_Advisor-URL some-Citysearch-URL some-Open_Table-URL some-ZAGAT-URL some-Zomato-URL
... ... ... ... ... ... ... ... ...
Run Code Online (Sandbox Code Playgroud)
像这样转动行的过程称为旋转。那么你
旋转连接的结果(在 MySQL 中,您可以使用条件聚合来实现):
SELECT
am.z_companyid_fk,
MAX( CASE WHEN us.isiteid= 1 THEN bizurl END ) AS "Yelp",
MAX( CASE WHEN us.isiteid= 2 THEN bizurl END ) AS "Urbanspoon",
MAX( CASE WHEN us.isiteid= 3 THEN bizurl END ) AS "Trip_Advisor",
MAX( CASE WHEN us.isiteid= 4 THEN bizurl END ) AS "Citysearch",
MAX( CASE WHEN us.isiteid= 5 THEN bizurl END ) AS "Open_Table",
MAX( CASE WHEN us.isiteid= 6 THEN bizurl END ) AS "ZAGAT",
MAX( CASE WHEN us.isiteid=32 THEN bizurl END ) AS "Zomato"
FROM
user_settings us
INNER JOIN asset_mst am ON (us.userid=am.userid)
GROUP BY
am.z_companyid_fk
Run Code Online (Sandbox Code Playgroud)在主 FROM 子句中与它们外部连接:
LEFT JOIN
(
SELECT
am.z_companyid_fk,
…
…
…
GROUP BY
am.z_companyid_fk
) AS url ON url.z_companyid_fk=a.z_companyid_pk
Run Code Online (Sandbox Code Playgroud)最后只引用主 SELECT 子句中的透视列名,而不是那些相关的子查询:
url."Yelp",
url."Urbanspoon",
url."Trip_Advisor",
url."Citysearch",
url."Open_Table",
url."ZAGAT",
url."Zomato",
Run Code Online (Sandbox Code Playgroud)最后,本组中相关的子查询:
(select if(count(*)>=1,"YES","NO") from webprofile where z_boxid_fk in(select z_boxid_pk from box_mst where z_companyid_fk=a.z_companyid_pk)) "V1_Website",
(select if(count(*)>=1,"YES","NO") from webapp_mst where z_companyid_fk=a.z_companyid_pk) "V2_Website",
(select if(count(*)>0,"YES","NO") from widget_mst where widget_status=1 and type in("templated-menu","menus") and z_companyid_fk=a.z_companyid_pk) "Widgets_with_my_menu",
(select if(count(imagehtml)>0,"YES","NO") from image_mst where length(imagehtml)>0 and z_companyid_fk=a.z_companyid_pk)"HTML_menus",
Run Code Online (Sandbox Code Playgroud)
都具有相同的模式:它们都用于COUNT(*)
确定是否显示YES
或NO
。根据您使用的数据库引擎,这可能效率低下。改用 EXISTS 可能是一个更好的主意。所以,你可以像这样重写上面的内容:
IF(EXISTS (select * from webprofile where z_boxid_fk in(select z_boxid_pk from box_mst where z_companyid_fk=a.z_companyid_pk)), 'YES', 'NO') AS "V1_Website",
IF(EXISTS (select * from webapp_mst where z_companyid_fk=a.z_companyid_pk), 'YES', 'NO') AS "V2_Website",
IF(EXISTS (select * from widget_mst where widget_status=1 and type in('templated-menu','menus') and z_companyid_fk=a.z_companyid_pk), 'YES', 'NO') AS "Widgets_with_my_menu",
IF(EXISTS (select * from image_mst where length(imagehtml)>0 and z_companyid_fk=a.z_companyid_pk), 'YES', 'NO') AS "HTML_menus",
Run Code Online (Sandbox Code Playgroud)
或者,您可以在每种情况下YES
只返回单词和一行(使用LIMIT 1
),NO
用 IFNULL 或 COALESCE替换可能的空结果:
IFNULL( (select 'YES' from webprofile where z_boxid_fk in(select z_boxid_pk from box_mst where z_companyid_fk=a.z_companyid_pk) LIMIT 1), 'NO') AS "V1_Website",
IFNULL( (select 'YES' from webapp_mst where z_companyid_fk=a.z_companyid_pk LIMIT 1), 'NO') AS "V2_Website",
IFNULL( (select 'YES' from widget_mst where widget_status=1 and type in('templated-menu','menus') and z_companyid_fk=a.z_companyid_pk LIMIT 1), 'NO') AS "Widgets_with_my_menu",
IFNULL( (select 'YES' from image_mst where length(imagehtml)>0 and z_companyid_fk=a.z_companyid_pk LIMIT 1), 'NO') AS "HTML_menus",
Run Code Online (Sandbox Code Playgroud)可能还有其他值得关注的部分,但这三个对我来说是突出的。
总之,我只想补充一点,第一个要点中的重写肯定会改进您在问题中发布的查询。另外两个我不太确定,所以我建议你独立尝试/测试它们。
归档时间: |
|
查看次数: |
171 次 |
最近记录: |