【发布时间】: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 UNSIGNED。INT(3)与TINYINT或SMALLINT类似。等等。