【发布时间】:2017-01-11 12:16:03
【问题描述】:
我正在寻找一种方法来加速以下示例查询,而无需对数据进行非规范化并将 task_customers 列引入表任务:
SELECT
tasks.id,
tasks.title,
COALESCE(tasksWithOnlyOneCustomer.task_customers, tasksWithMoreThanOneCustomer.task_customers) task_customers
FROM tasks
LEFT JOIN (
SELECT
tcl.task_id,
GROUP_CONCAT(CONCAT(c.first_name, ' ', c.last_name) SEPARATOR ', ') task_customers,
COUNT(tcl.customer_id) c
FROM tasks_customers_links tcl
LEFT JOIN customers c ON c.id = tcl.customer_id
WHERE c.id IS NOT NULL
GROUP BY tcl.task_id
HAVING c = 1
) tasksWithOnlyOneCustomer ON tasksWithOnlyOneCustomer.task_id = tasks.id
LEFT JOIN (
SELECT
tcl.task_id,
GROUP_CONCAT(CONCAT(c.first_name, ' ', c.last_name) SEPARATOR ', ') task_customers,
COUNT(tcl.customer_id) c
FROM tasks_customers_links tcl
LEFT JOIN customers c ON c.id = tcl.customer_id
WHERE c.id IS NOT NULL
GROUP BY tcl.task_id
HAVING c > 1
) tasksWithMoreThanOneCustomer ON tasksWithMoreThanOneCustomer.task_id = tasks.id
ORDER BY
ISNULL(tasksWithOnlyOneCustomer.task_customers) ASC, /* ORDER NULLS AT THE END */
tasksWithOnlyOneCustomer.task_customers ASC,
ISNULL(tasksWithMoreThanOneCustomer.task_customers) ASC, /* ORDER NULLS AT THE END */
tasksWithMoreThanOneCustomer.task_customers ASC
表结构如下:
CREATE TABLE tasks (
id INT NOT NULL,
title VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE customers (
id INT NOT NULL,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE tasks_customers_links (
id INT NOT NULL AUTO_INCREMENT,
task_id INT NOT NULL,
customer_id INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (task_id) REFERENCES tasks(id),
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
INSERT INTO tasks (id, title) VALUES (1, 'Wake Up!'), (2, 'Eat!'), (3, 'Sleep!');
INSERT INTO customers (id, first_name, last_name) VALUES (1, 'Homer', 'Simpson'), (2, 'Bart', 'Simpson'), (3, 'Marge', 'Simpson');
INSERT INTO tasks_customers_links (task_id, customer_id) VALUES (1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (3, 3);
在两个表中都有超过 10 万条记录的真实案例场景中执行此查询时,它确实会变慢并创建临时表。因此,我正在寻找一种解决方案,如果可能的话,可以在不进行数据非规范化的情况下加快处理速度。
【问题讨论】:
标签: mysql many-to-many left-join query-optimization