我正在做一些相当大的一组数据,并试图从四个不同的数据组合的每个组合创建一个查询。所有这些组合形成了惊人的1.22亿行。然后,我试图找到一个小于一定数量的权重,并按照从最高到最低的另一个值进行排序。MySQL查询与小于和ORDER BY DESC
我可以使用weight < x
没问题。
我可以使用weight < x order by height ASC
没问题。
当x位于上下两端时,我甚至可以使用weight < x order by height DESC
。但是一旦它开始蔓延到中间,它就会很快从几秒钟上升到几分钟,直到“我不会等那么久。”
有什么想法? (该名称已经更改,但种类却没有)
的创建:
CREATE TABLE combinations (
id bigint(20) unsigned NOT NULL auto_increment,
up smallint(2) NOT NULL,
left smallint(2) NOT NULL,
right smallint(2) NOT NULL,
down smallint(2) NOT NULL,
weight decimal(5,1) NOT NULL,
width smallint(3) NOT NULL,
forward decimal(6,2) NOT NULL,
backwards decimal(5,2) NOT NULL,
in decimal(7,2) NOT NULL,
out smallint(3) NOT NULL,
height smallint(3) NOT NULL,
diameter decimal(7,2) NOT NULL,
PRIMARY KEY (id)
);
指数
ALTER TABLE combinations ADD INDEX weight_and_height(weight,height);
查询
SELECT * FROM combinations WHERE weight < 20 ORDER BY height DESC limit 0,5;
的解释
| id | select type | table | type | possible_keys | key | key_len | ref | rows | extra |
| 1 | simple | combinations | index | weight_and_height | weight_and_height | 5 | NULL | 10 | using where |
我认为查询计划会自动做到这一点?首先通过
johnrom
看看'EXPLAINs'。您可能会发现有些使用索引,有些则不使用。优化器无法准确地做出两者之间的决定。我怀疑你正在看到一个它做出错误选择的案例。 –
2个范围(重量和高度)不能同时使用。想象一下按字母顺序排列的人员列表 - 按姓氏和名字排序。现在假设你想找到所有拥有我的姓名缩写的人(J.,R.)。'INDEX(last,first)'没有用,它只是简单地扫描所有'last LIKE'J%''检查每个一个用于'R'。你需要一个2D索引。我看到的最接近的是[纬度/经度搜索](http://mysql.rjweb.org/doc.php/latlng),它可能适用于您的应用程序。 –