我该如何改进?它需要大约半秒钟,它只是一个演示查询。
这里的问题是ORDER BY,但我不能没有它。对于something
表中缺少的记录,我还需要LEFT JOIN的空行。
SELECT c.name
FROM customers c
LEFT JOIN something s USING(customer_id)
ORDER BY s.test DESC LIMIT 25
数据库架构:
CREATE TABLE customers (
customer_id int(11) NOT NULL AUTO_INCREMENT,
name text NOT NULL,
PRIMARY KEY (customer_id),
KEY namne (name(999))
) ENGINE=MyISAM AUTO_INCREMENT=100001 DEFAULT CHARSET=latin
CREATE TABLE something (
id int(11) NOT NULL AUTO_INCREMENT,
customer_id int(11) NOT NULL,
text longtext NOT NULL,
test varchar(5) NOT NULL,
PRIMARY KEY (id),
KEY customer_id (customer_id),
KEY text (text(999)),
KEY test (test),
KEY asdasd (customer_id,test)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=latin1
说明:
+------+-------------+-------+------+--------------------+--------+---------+--------------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+--------------------+--------+---------+--------------------+--------+---------------------------------+
| 1 | SIMPLE | c | ALL | NULL | NULL | NULL | NULL | 100000 | Using temporary; Using filesort |
| 1 | SIMPLE | s | ref | customer_id,asdasd | asdasd | 4 | test.c.customer_id | 2 | Using index |
+------+-------------+-------+------+--------------------+--------+---------+--------------------+--------+---------------------------------+
答案 0 :(得分:0)
LEFT JOIN看起来不像这里。如果用INNER JOIN替换它,引擎将能够使用KEY test (test)
作为ORDER BY子句。所以你需要的就是这个:
SELECT c.name
FROM customers c
INNER JOIN something s USING(customer_id)
ORDER BY s.test DESC LIMIT 25
但要获得与LEFT JOIN完全相同的结果,您可以将两个快速查询与UNION ALL
结合使用:
(
SELECT c.name
FROM customers c
LEFT JOIN something s USING(customer_id)
ORDER BY s.test DESC LIMIT 25
) UNION ALL (
SELECT c.name
FROM customers c
LEFT JOIN something s USING(customer_id)
WHERE s.customer_id IS NULL
LIMIT 25
)
LIMIT 25
答案 1 :(得分:0)
VARCHAR(..)
而非TEXT
中使用一些合理的限制。INDEX(a)
在INDEX(a,b)
。时是多余的
更快的速度:
SELECT name
FROM (
( SELECT c.name, s.test
FROM customers c
JOIN something s USING(customer_id)
ORDER BY s.test DESC
LIMIT 25
)
UNION ALL
( SELECT c.name, NULL
FROM customers c
LEFT JOIN something s USING(customer_id)
WHERE s.test IS NULL
LIMIT 25
)
) AS x
ORDER BY test DESC
LIMIT 25
并且
INDEX(test, customer_id)