小于的MySQL查询,按描述排序

小于的MySQL查询,按描述排序,mysql,indexing,sql-order-by,where,where-clause,Mysql,Indexing,Sql Order By,Where,Where Clause,我正在处理一组相当大的数据,并试图从四个不同数据段的每个组合中创建一个查询。所有这些碎片加起来形成了惊人的122000000行。然后,我试图找到一个小于某个数量的权重,并按另一个值从高到低排序 我可以使用重量

我正在处理一组相当大的数据,并试图从四个不同数据段的每个组合中创建一个查询。所有这些碎片加起来形成了惊人的122000000行。然后,我试图找到一个小于某个数量的权重,并按另一个值从高到低排序

我可以使用重量 我可以使用重量 当x在上端和下端附近时,我甚至可以使用weight 有什么想法吗?名称已更改,但类型尚未更改

创建:

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;

您的索引仅用于根据权重进行筛选。以下是步骤:

使用任何以权重开头的索引可以找到权重小于x的所有行 那一组是按高度排序的。。。 跳过0个偏移行; 交付5个限制行。 潜在的昂贵部分是步骤1。可能在你的例子中,20是列表中最早的一个。事实上,解释估计这个集合只有10行。对于较大的x值,步骤1需要更长的时间。这是不可避免的

处理步骤1中的所有行;因此,步骤2的时间也不同。5.6有一个额外的优化,部分结合了步骤2、3、4

你真的在做选择*?例如,如果您只需要选择id,那么INDEXweight、height、id将运行得更快,因为查询可以完全在索引中执行

如果您确实需要您提到的查询,那么这将运行得更快:

SELECT c.*
    FROM (
        SELECT id FROM combinations
            WHERE weight < 20 ORDER BY height DESC limit 0,5
         ) ids
    JOIN combinations AS c  USING(id)
    ORDER BY height DESC;
注:

子查询正在使用前面提到的索引。 子查询只传递5行。 外部选择只有5行需要处理。 id是索引的,因为它是主键,所以连接是有效的。 回复:标题小于和描述不重要。
我以为查询计划会自动做到这一点?首先按<权重索引的限制,然后按高度索引的顺序,然后根据从内存中找到的行的限制进行选择。令人困惑的是,重量<50所有122m行运行良好,重量<4几千行运行良好,但当返回约60m行时,重量<20,则会断裂。即使是90米左右的行也可以很好地工作,重量<32看看下面的解释。您可能会发现,有些使用索引,有些不使用。优化器无法准确地在两者之间做出决策。我怀疑你看到的是一个案例,它做出了错误的选择。体重和身高不能同时使用。想象一张按字母顺序排列的人名单——按姓和名排序。现在假设你想找到所有有我名字首字母J,R的人。使用INDEXlast没有用,首先,它将简单地扫描所有最后的人,就像“J%”检查每个人的R。你需要一个2D索引。我见过的最接近的是a,它可能适合你的应用。明天我将尝试你修改后的加入。如果这不是解决办法,我还有一些其他想法。主要思想是重量不需要是小数。然而,因为这似乎不是瓶颈,所以这可能是一个毫无意义的优化。我会回来报到的!是的,我怀疑十进制和浮点等是否重要。你有smallint2;您是否只需要两位数字?SMALLINT是2个字节;TINYINT是1字节范围-128..127或TINYINT无符号0..255。
SELECT c.*
    FROM (
        SELECT id FROM combinations
            WHERE weight < 20 ORDER BY height DESC limit 0,5
         ) ids
    JOIN combinations AS c  USING(id)
    ORDER BY height DESC;