【问题标题】:MySQL increase ordering speed by dynamic formulaMySQL通过动态公式提高排序速度
【发布时间】:2018-06-30 06:02:36
【问题描述】:

我有一个包含多个列的 MySQL 表和一个基于不同列并针对不同查询而变化的效率公式。该表包含超过 1000 万个条目并且是静态的,因此不会添加新条目。

CREATE TABLE `table1` (
    `col1` INT(2) UNSIGNED NOT NULL, # this is an ID from another table used as a filter
    `col2` INT(5) NOT NULL,          # about 20 fixed integer
    `col3` INT(1) NULL DEFAULT NULL,
    `col4` DECIMAL(4,2) NOT NULL,    # fixed decimals -2:0.5:2
    `col5` DECIMAL(4,2) NOT NULL,    # fixed decimal 5:0.5:10
    `col6` INT(2) NOT NULL,
    `col7` INT(2) NOT NULL,          # fixed integer 0:5:15
    `col8` DECIMAL(4,2) NOT NULL,    # unknown decimals
    `col9` DECIMAL(4,2) NOT NULL,    # unknown decimals
    `col10` DECIMAL(4,2) NOT NULL,   # unknown decimals
    `col11` INT(3) NOT NULL,         # unknown integer
    `col12` DECIMAL(4,2) NOT NULL,   # unknown decimals
    `col13` DECIMAL(4,2) NOT NULL,   # unknown decimals
    `col14` DECIMAL(4,2) NOT NULL,   # unknown decimals
    `col15` DECIMAL(4,2) NOT NULL,   # unknown decimals
    INDEX `Index1` (`col1`, `col5`, `col4`, `col2`, `col7`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;

这是两个常见的自动生成的查询:

SELECT col6,col5,col2,col3,col13,col14,col7,col1,col11,
       col13*col14*col2/col6 AS efficiency
    FROM `table1`
    WHERE `col1` IN (19,1,2,39,40,34,35)
      AND `col5` = '6'
      AND col2 >= '1000' AND col2 <= '5600'
      AND `col4` = '0'
      AND col7 >= 0 AND col7 <= 15
      AND col13 >= 3.00 AND col13 <= 4.50
      AND col14 >= 0.60
    ORDER BY efficiency ASC, col13 ASC
    LIMIT 0, 1;

SELECT col6,col5,col2,col3,col8,col9,col10,col11,col12,col7,col1,col8*col10*col2*col9/col6 AS efficiency
    FROM `table1`
    WHERE `col1` IN (8,11,9,12,16,17,19,24,42,20,43,21,44,22,45,23,25,1,2,3,4,5,28,31,27,39,40,41,34,35)
      AND `col5` = '6' AND col2 >= '1000' AND col2 <= '5600'
      AND `col4` = '0'
      AND col7 >= 0 AND col7 <= 15
      AND col8 >= 0.50
      AND col9 >= 0.35
      AND col10 >= 0.40
      AND col11 <= 15
      AND col12 >= 0.30
    ORDER BY efficiency ASC, col6 DESC
    LIMIT 0, 1

第二个查询包含 col1 的所有值以强制使用索引

没有 ORDER BY 子句的查询比有它的查询要快得多。

我有很多这样的表,所以数据库总体需要大约 65 GB 的存储空间。另一个索引会增加所需的空间,对吧?

在没有 order 和 limit 子句的情况下处理查询的时间是 0,390 秒。 (+ 1,922 秒的网络获得数百个条目)。这两个子句都需要 1,781 秒。

因为效率公式有时不同,会产生浮点数,所以附加索引似乎是错误的方式。

另一个问题是,我必须再次对相同的结果进行排序。目前,我只是再次调用查询,这需要(如预期)双倍的时间。有没有办法对给定的结果再次排序?

查询必须在 where 子句之后处理几百个条目。我认为这应该比 2 秒快得多。

这个场景的瓶颈是什么?

【问题讨论】:

  • 您可以使用 内存引擎 创建一个新表,您可以查看文档dev.mysql.com/doc/refman/5.7/en/memory-storage-engine.html,当您完成查询后,您只需删除该表, 释放内存
  • 更新您的问题并添加您的相关索引
  • 因此,如果您不添加任何新条目,只需创建一个新列添加索引以 id 使用所需数据更新新列。这应该会提高你的表现。
  • @knetsi - MEMORY 不可能比一个足够小以保持缓存在 RAM 中的 InnoDB 表快。
  • 在适当的情况下将 INT(2) 更改为 TINYINT UNSIGNEDINT(3)TINYINTSMALLINT 类似。等等。

标签: mysql sorting indexing


【解决方案1】:

因为效率公式有时不同,会产生浮点数,所以附加索引似乎是错误的方式。

一种选择是绝对使用索引。为什么效率公式不同?如果您只有几个这样的公式,我建议将它们存储在同一个或不同的表中,并在每一列上放置一个索引。是的,您可以对浮点数进行索引。

您可以使用触发器使公式保持最新(在其他数据库中,您可以简单地使用计算列,但 MySQL 不支持 v8 之前的那些)。

查询必须在 where 子句之后处理大约 800 个条目。

这与 30 分钟的查询时间不一致,除非您的行非常非常宽。扫描具有数百万行的表需要时间,但需要几十秒,而不是几十分钟。如果您可以将条件调整为严格相等条件(没有or,没有in),那么可以使用索引快速找到800 个条目。

正如现在所写,索引不会特别有用,除非col2 具有高度选择性。

【讨论】:

  • 我将尝试在效率公式的结果中添加一列,并在其上放置一个索引(+旧的?)。除非 col2 具有高度选择性,否则为什么索引没有帮助?
  • @Marius 。 . .大多数比较是不等式。索引在相等条件下效果最好。
【解决方案2】:
  • 由于表是static,因此将每种数据类型缩小到最小。如果这是问题的一部分,这将减少 I/O。
  • 查看可能的查询。发现使用 = 测试了哪些列(如您的示例中的 col2 和 col4)。
  • 基于 = 列构建各种 2 列索引。
  • 将其中一些索引延长 一个IN 或“范围”中使用的列。
  • 创建的索引不要超过十几个。
  • 如果您通常在计算 col1*col2/col3 AS efficiency,那么,请把它写成一列。

告诉我们您使用的数字类型(费用、计量、人员、日期/日期时间等);它可以帮助提供进一步的建议。

具体说明基于提出的查询:

这两个查询都将受益于

INDEX(col4, col5, one-other-col)  -- where 4 and 5 are in either order

这会将所有= 测试放在索引中的首位。第三列应该是最有选择性的列。 (当然,这可能是一场猜谜游戏。)

IN= 差,但不如&lt; 之类的范围差(或者像col7). So it is hard to say whethercol1` 这样的对在索引中很有用。

使用一个“范围”列后,优化器将忽略索引中的任何其他列。因此,在原始索引中,它无法到达col7,因为col2 是一个范围。

【讨论】:

  • “基于 = 列构建各种 2 列索引”是什么意思?我目前只有一个索引,数据库为 65 GB。很多索引不会迅速增加大小吗?
  • @brnk - 我添加了一些细节。
猜你喜欢
  • 1970-01-01
  • 2011-06-14
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-13
  • 2019-04-25
  • 1970-01-01
相关资源
最近更新 更多