我有一个使用phpymyadmin的网站,当我进入“状态”时,它告诉我以下内容:“不使用索引的连接数。如果该值不为0,则应仔细检查以下内容的索引:你的桌子。”该数字不为0,目前为101,但在本周末重置服务器之前,该数字已超过24K。
这是我的查询示例。不知道我的JOINS哪里出了问题,有人可以帮助我让我知道是否丢失了某些东西,或者我是否在这里多余,或者也许对如何处理索引情况做了一些解释。
SELECT pe_projects . *
, pe_project_status.status_t
, pe_project_status.orderby
, pe_pocs.first_name AS 'poc_first_name'
, pe_pocs.last_name 'poc_last_name'
, pe_clients.id AS 'client_id'
, pe_clients.short_name
, pe_employees.first_name AS 'pe_first_name'
, pe_employees.last_name AS 'pe_last_name'
, (SELECT COUNT(pe_instrument_tracking.id)
FROM pe_instrument_tracking
WHERE pe_instrument_tracking.project_id = pe_projects.id
) AS total_inst
, (SELECT (SELECT COUNT(pe_instrument_tracking.id)
FROM pe_instrument_tracking
WHERE pe_instrument_tracking.project_id = pe_projects.id
AND pe_instrument_tracking.ordered IS NOT NULL
AND pe_instrument_tracking.ordered <> '0000-00-00'
)/COUNT(pe_instrument_tracking.id) *100
FROM pe_instrument_tracking
WHERE pe_instrument_tracking.project_id = pe_projects.id
) AS ordered_per
, (SELECT (SELECT COUNT(pe_instrument_tracking.id)
FROM pe_instrument_tracking
WHERE pe_instrument_tracking.project_id = pe_projects.id
AND pe_instrument_tracking.received IS NOT NULL
AND pe_instrument_tracking.received <> '0000-00-00'
)/COUNT(pe_instrument_tracking.id) *100
FROM pe_instrument_tracking
WHERE pe_instrument_tracking.project_id = pe_projects.id
) AS received_per
, (SELECT (SELECT COUNT(pe_instrument_tracking.id)
FROM pe_instrument_tracking
WHERE pe_instrument_tracking.project_id = pe_projects.id
AND pe_instrument_tracking.installed IS NOT NULL
AND pe_instrument_tracking.installed <> '0000-00-00'
)/COUNT(pe_instrument_tracking.id) *100
FROM pe_instrument_tracking
WHERE pe_instrument_tracking.project_id = pe_projects.id
) AS installed_per
, (SELECT (SELECT COUNT(pe_instrument_tracking.id)
FROM pe_instrument_tracking
WHERE pe_instrument_tracking.project_id = pe_projects.id
AND pe_instrument_tracking.tested IS NOT NULL
AND pe_instrument_tracking.tested <> '0000-00-00'
)/COUNT(pe_instrument_tracking.id) *100
FROM pe_instrument_tracking
WHERE pe_instrument_tracking.project_id = pe_projects.id
) AS tested_per
FROM pe_projects
JOIN pe_project_status ON pe_projects.status_id = pe_project_status.id
JOIN pe_pocs ON pe_projects.client_contact_id = pe_pocs.id
JOIN pe_clients ON pe_projects.client_id = pe_clients.id
JOIN pe_employees ON pe_projects.employee_id = pe_employees.id
WHERE NOT pe_projects.deleted
AND pe_projects.department='1'
答案 0 :(得分:1)
很难说应该从哪里开始,但是据我所知,根据我编辑之前的问题
所有这些都可能导致错误,难以识别并且难以修复。
x <> NULL
是NULL
,这是虚假的,因此您无需单独测试NULL。COUNT(*)
而不是COUNT(table.id)
,这更具可读性,但是如果table.id
并不意味着它看起来像什么,也许这是不对的。SELECT
在可读性和性能上都是一个很大的危险信号。您可以依靠以下事实来摆脱它们:不使用COUNT(*)
时,COUNT不计算NULL
个。SELECT pe_projects.*
, pe_project_status.status_t
, pe_project_status.orderby
, pe_pocs.first_name AS 'poc_first_name'
, pe_pocs.last_name AS 'poc_last_name'
, pe_clients.id AS 'client_id'
, pe_clients.short_name
, pe_employees.first_name AS 'pe_first_name'
, pe_employees.last_name AS 'pe_last_name'
, (SELECT COUNT(*)
FROM pe_instrument_tracking pit
WHERE pit.project_id = pe_projects.id
) AS total_inst
, (SELECT COUNT(
CASE WHEN pit_o.ordered <> '0000-00-00' THEN pit_o.id END
) / COUNT(*) * 100
FROM pe_instrument_tracking pit_o
WHERE pit_o.project_id = pe_projects.id
) AS ordered_per
, (SELECT COUNT(
CASE WHEN pit_r.received <> '0000-00-00' THEN pit_r.id END
) / COUNT(*) * 100
FROM pe_instrument_tracking pit_r
WHERE pit_r.project_id = pe_projects.id
) AS received_per
, (SELECT COUNT(
CASE WHEN pit_i.installed <> '0000-00-00' THEN pit_i.id END
) / COUNT(*) * 100
FROM pe_instrument_tracking pit_i
WHERE pit_i.project_id = pe_projects.id
) AS installed_per
, (SELECT COUNT(
CASE WHEN pit_t.tested <> '0000-00-00' THEN pit_t.id END
) / COUNT(*) * 100
FROM pe_instrument_tracking pit_t
WHERE pit_t.project_id = pe_projects.id
) AS tested_per
FROM pe_projects
LEFT JOIN pe_project_status ON pe_projects.status_id = pe_project_status.id
LEFT JOIN pe_pocs ON pe_projects.client_contact_id = pe_pocs.id
LEFT JOIN pe_clients ON pe_projects.client_id = pe_clients.id
LEFT JOIN pe_employees ON pe_projects.employee_id = pe_employees.id
WHERE NOT pe_projects.deleted
AND pe_projects.department = '1'
以上仍然不是很好。特别是,针对单个表pe_instrument_tracking
有五个子查询。假设您使用的是MySQL的最新版本,则可以使用“派生表”类型的子查询来解决此问题:
SELECT pe_projects.*
, pe_project_status.status_t
, pe_project_status.orderby
, pe_pocs.first_name AS 'poc_first_name'
, pe_pocs.last_name AS 'poc_last_name'
, pe_clients.id AS 'client_id'
, pe_clients.short_name
, pe_employees.first_name AS 'pe_first_name'
, pe_employees.last_name AS 'pe_last_name'
, pit.total AS total_inst
, pit.ordered AS ordered_per
, pit.received AS received_per
, pit.installed AS installed_per
, pit.tested AS tested_per
FROM pe_projects
LEFT JOIN pe_project_status ON pe_projects.status_id = pe_project_status.id
LEFT JOIN pe_pocs ON pe_projects.client_contact_id = pe_pocs.id
LEFT JOIN pe_clients ON pe_projects.client_id = pe_clients.id
LEFT JOIN pe_employees ON pe_projects.employee_id = pe_employees.id
LEFT JOIN (SELECT COUNT(*) AS total
, 100
* COUNT(CASE WHEN pe_instrument_tracking.ordered <> '0000-00-00' THEN 1 END)
/ COUNT(*) AS ordered
, 100
* COUNT(CASE WHEN pe_instrument_tracking.received <> '0000-00-00' THEN 1 END)
/ COUNT(*) AS received
, 100
* COUNT(CASE WHEN pe_instrument_tracking.installed <> '0000-00-00' THEN 1 END)
/ COUNT(*) AS installed
, 100
* COUNT(CASE WHEN pe_instrument_tracking.tested <> '0000-00-00' THEN 1 END)
/ COUNT(*) AS tested
FROM pe_instrument_tracking ON pe_instrument_tracking.project_id = pe_projects.id
) AS pit
WHERE NOT pe_projects.deleted
AND pe_projects.department = '1'
但是现在您有了一个更简短,更易懂的查询,您可以希望开始思考需要有效运行哪种键和索引。