【发布时间】:2014-12-24 04:10:59
【问题描述】:
我编写了一个处理权限的复杂查询,为了使其工作,它在 IF 语句内包含一个嵌套子查询,以仅匹配用户有权访问的那些项目,并匹配条件。
我不确定为什么它运行缓慢,希望能帮助我了解如何调查查询速度。
概述如下:(下面的完整查询)
//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,这样可以更好地利用索引,并且不需要对每一行都执行。 -
我发布的实际查询比较复杂,但总结起来只是为了检索记录匹配权限。
标签: mysql select subquery where