我寫了一個處理權限的複雜查詢,爲了使其工作,它在IF語句中包含一個嵌套的子查詢,以僅匹配用戶有權訪問的項目並匹配條件。爲什麼SELECT語句嵌套WHERE子查詢在MYSQL中運行緩慢?
我不確定它爲什麼運行緩慢,並希望得到如何調查查詢速度的幫助。
由於這是什麼樣子的輪廓:(完整的查詢下)
//Main table has many records
SELECT some field FROM tbl join some table WHERE
IF (
Subquery (Sub-subquery())
)
完整的查詢:
-- Get Account By User Assign to
SELECT
-- SQL_CALC_FOUND_ROWS acc.account_id,
acc.`is_delete`,
acc.test, CONCAT('<strong>',acc.account_name,'</strong>') AS account_name_alias,
CONCAT(u.first_name,' ',u.last_name) created_by_alias,
a.account_type_name,
i.industry_name,
CONCAT(u1.first_name,' ',u1.last_name)
modified_by_alias,
isp.isp_name,
sp.service_plan_name,
c.country_name,
ci.city_name,
d.district_name,
co.commune_name
FROM crm_accounts AS acc
INNER JOIN crm_accounts_assignments asm ON acc.`account_id` = asm.`account_id`
LEFT JOIN crm_users u ON acc.created_by = u.user_id
LEFT JOIN crm_users u1 ON acc.modified_by = u1.user_id
LEFT JOIN crm_account_types a ON acc.account_type = a.account_type_id
LEFT JOIN crm_industries i ON acc.industry_id = i.industry_id
LEFT JOIN crm_isp_lists isp ON acc.isp_id = isp.isp_id
LEFT JOIN crm_service_plans sp ON acc.service_plan_id = sp.service_plan_id
LEFT JOIN crm_countries c ON acc.country_id = c.country_id
LEFT JOIN crm_cities ci ON acc.city_id = ci.city_id
LEFT JOIN crm_districts d ON acc.district_id = d.district_id
LEFT JOIN crm_communes co ON acc.commune_id = co.commune_id
WHERE acc.is_delete = 0
//This my sub query
AND
IF (
(
CASE asm.`assign_type`
WHEN
EXISTS
(
SELECT 1 FROM crm_user_param_users upu1
INNER JOIN crm_users us1 ON upu1.`user1_id` = us1.`user_id`
WHERE upu1.`user_id` = 7 AND upu1.`user1_id` = asm.`assign_to_id`
AND us1.`role_id` !=2 #User the same Role could not access each other
OR EXISTS
(
-- The same Role will be allow if exist at custom share access
SELECT 1 FROM `crm_user_param_modules_custom_accesses` mca1
WHERE mca1.`module_id` = 1 AND mca1.`user_id` = 7 AND mca1.`role_id` = 2 LIMIT 1
) GROUP BY upu1.`user1_id` LIMIT 1
)
OR EXISTS
(
-- Only account created by current user
SELECT 1 FROM crm_user_param_users upu2
INNER JOIN crm_users us2 ON upu2.`user1_id` = us2.`user_id`
WHERE upu2.`user_id` = 7 AND acc.`created_by` = upu2.`user1_id`
AND us2.`role_id` !=2 #User the same Role could not access each other
OR EXISTS
(
-- The same Role will be allow if exist at custom share access
SELECT 1 FROM `crm_user_param_modules_custom_accesses` mca2
WHERE mca2.`module_id` = 1 AND mca2.`user_id` = 7 AND mca2.`role_id` =2 LIMIT 1
) GROUP BY upu2.`user1_id` LIMIT 1
)
OR acc.`created_by` = 7
THEN 1
ELSE 0
END
)= 1, 1,0
) = 1
OR
IF (
(
CASE asm.`assign_type`
WHEN
EXISTS
(
SELECT 1 FROM `crm_user_param_groups` upg1
INNER JOIN crm_users us1 ON upg1.`user_id` = us1.`user_id`
WHERE upg1.`user_id` = 7 AND upg1.`group_id` = asm.`assign_to_id`
AND us1.`role_id` !=2 #User the same Role could not access each other
-- The same Role will be allow if exist at custom share access --
OR EXISTS
(
SELECT 1 FROM `crm_user_param_modules_custom_accesses` mca1
WHERE mca1.`module_id` = 1 AND mca1.`user_id` = 7 AND mca1.`role_id` = 2 LIMIT 1
) LIMIT 1
)
-- Only Account created by current user group --
OR EXISTS
(
SELECT 1 FROM `crm_user_param_groups` upg2
INNER JOIN crm_users us2 ON upg2.`user_id` = us2.`user_id`
WHERE upg2.`group_id` = asm.`assign_to_id` AND us2.`user_id` = acc.`created_by`
AND us2.`role_id` !=2 #User the same Role could not access each other
OR EXISTS
(
-- The same Role will be allow if exist at custom share access --
SELECT 1 FROM `crm_user_param_modules_custom_accesses` mca2
WHERE mca2.`module_id` = 1 AND mca2.`user_id` = 7 AND mca2.`role_id` =2 LIMIT 1
) LIMIT 1
)
OR acc.`created_by` = 7
THEN 2
ELSE 0
END
)= 2, 1,0
) = 1
請發佈您正在使用的實際查詢,或至少比此更完整的替身。 'WHERE'中的子查詢通常可以重寫爲'JOIN',它可以更好地使用索引,並且不需要爲每行執行。 –
我發佈實際查詢它複雜化,但總結只爲檢索記錄匹配權限。 – Meas