Kow*_*hik 13 mysql sql database indexing
我有一个名为'test'的简单MySQL表,有两列:
我根据'textcol'列在表中创建了一个索引.但是,ORDER BY查询似乎没有使用索引,即在textcol上使用ORDER BY的简单查询上的EXPLAIN语句在其输出的Key列中显示NULL,并且还使用filesort.
任何用于进行更改以帮助使用ORDER by query的索引的指针对我都很有用.
MySQL版本由"mysql --version"命令给出:
mysql Ver 14.14 Distrib 5.1.58,debian-linux-gnu(x86_64)使用readline 6.2
mysql> CREATE TABLE test (id INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), textcol VARCHAR(3000));
Query OK, 0 rows affected (0.05 sec)
mysql> DESCRIBE test;
+---------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| textcol | varchar(3000) | YES | | NULL | |
+---------+---------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> CREATE INDEX textcolindex ON test (textcol);
Query OK, 0 rows affected, 2 warnings (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEX FROM test;
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| test | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | |
| test | 1 | textcolindex | 1 | textcol | A | NULL | 1000 | NULL | YES | BTREE | |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.00 sec)
mysql> INSERT INTO test (textcol) VALUES ('test1');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO test (textcol) VALUES ('test2');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO test (textcol) VALUES ('test3');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO test (textcol) VALUES ('test4');
Query OK, 1 row affected (0.00 sec)
mysql> EXPLAIN SELECT * FROM test ORDER BY textcol;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | test | ALL | NULL | NULL | NULL | NULL | 4 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)
mysql> EXPLAIN SELECT * FROM test ORDER BY id;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | test | ALL | NULL | NULL | NULL | NULL | 4 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
由于它必须加载整个表来回答查询并且排序4个元素很便宜,查询优化器可能只是避免触及索引.大表还会发生吗?
请注意,varchar(3000)列不能是覆盖索引,因为MySQL不会包含多于索引中varchar的前768个字节.
如果您希望查询仅读取索引,则索引必须包含您要SELECT
在其中的每个列.在innodb上,一旦你使textcol足够小,它应该开始为你的双列表工作; 在MyISAM上,您需要自己包含主键列,例如CREATE INDEX textcolindex ON test (textcol,id);
我遇到了同样的问题。MySQL是愚蠢的。仅供参考:我有一张包含超过 500,000,000 条记录的表。我想:
select * from table order by tid limit 10000000, 10;
Run Code Online (Sandbox Code Playgroud)
tid 是表中的主键,由 mysql 自动索引。
这花了很长时间,我取消了查询。然后我让mysql“解释”查询并认识到它不会使用主键的索引。从 mysql 阅读了许多文档后,我试图通过“USE INDEX(...)”强制 mysql 使用索引,但 dis 也不起作用。然后我意识到mysql似乎总是将where子句与order by子句相关联。因此,我尝试使用触及索引的条件扩展 where 子句。我结束了:
select * from table use index (PRIMARY) where tid > 0 order by tid limit 10000000, 10;
Run Code Online (Sandbox Code Playgroud)
其中 tid 是表中的主键,是从 1 开始的自动增量值。
在我让 mysql 向我解释查询之后,这奏效了。看哪:查询只用了 4 秒。
有关ORDER BY优化的一些有用的文章:
http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/
http://opsmonkey.blogspot.co.uk/2009/03/mysql-query-optimization-for-order-by.html
如上所述,将varchar保持在767并为订单添加一个键:
CREATE TABLE test (
id INTEGER NOT NULL AUTO_INCREMENT,
textcol VARCHAR(767),
PRIMARY KEY(id),
KEY orderby (`textcol`)
);
Run Code Online (Sandbox Code Playgroud)
要避免filesorts
添加额外的'WHERE'参数,请使用多列索引扩展'orderby'索引键:
CREATE TABLE test (
id INTEGER NOT NULL AUTO_INCREMENT,
tom INT(11) NOT NULL DEFAULT 0,
gerry INT(11) NOT NULL DEFAULT 0,
textcol VARCHAR(767),
PRIMARY KEY(id),
KEY orderby (`tom`,`gerry`, `textcol`)
);
Run Code Online (Sandbox Code Playgroud)
也:
INSERT INTO test (tom, gerry, textcol) VALUES (1,2,'test4');
INSERT INTO test (tom, gerry, textcol) VALUES (1,2,'test2');
EXPLAIN SELECT id, textcol FROM test WHERE tom = 1 AND gerry =2 ORDER BY textcol;
Run Code Online (Sandbox Code Playgroud)
额外:'使用地点; 使用索引'
归档时间: |
|
查看次数: |
19704 次 |
最近记录: |