Mysql 因为某种原因。可能是因为MAX和MIN仍然让我扫描所有数据?下面答案中建议的索引确实很有帮助。@JeffUK-到目前为止,获取行是任何查询的主要部分。这个查询需要获取所有的行。太棒了!解释告诉我,它仍然选择在名称上使用索引,但在我删除后,它的速度快了大约5

Mysql 因为某种原因。可能是因为MAX和MIN仍然让我扫描所有数据?下面答案中建议的索引确实很有帮助。@JeffUK-到目前为止,获取行是任何查询的主要部分。这个查询需要获取所有的行。太棒了!解释告诉我,它仍然选择在名称上使用索引,但在我删除后,它的速度快了大约5,mysql,sql,database,performance,Mysql,Sql,Database,Performance,因为某种原因。可能是因为MAX和MIN仍然让我扫描所有数据?下面答案中建议的索引确实很有帮助。@JeffUK-到目前为止,获取行是任何查询的主要部分。这个查询需要获取所有的行。太棒了!解释告诉我,它仍然选择在名称上使用索引,但在我删除后,它的速度快了大约5倍!:如果你能解释一下你是如何按照索引的顺序查看字段的,那就太好了。名称首先用于GROUP BY子句,然后时间用于每个组中的聚合函数,特别是将改进MAX和MIN函数。出于好奇,你可以交换时间和价格,看看什么是最好的。谢谢!看起来非常接近,但第二



因为某种原因。可能是因为MAX和MIN仍然让我扫描所有数据?下面答案中建议的索引确实很有帮助。@JeffUK-到目前为止,获取行是任何查询的主要部分。这个查询需要获取所有的行。太棒了!解释告诉我,它仍然选择在名称上使用索引,但在我删除后,它的速度快了大约5倍!:如果你能解释一下你是如何按照索引的顺序查看字段的,那就太好了。名称首先用于GROUP BY子句,然后时间用于每个组中的聚合函数,特别是将改进MAX和MIN函数。出于好奇,你可以交换时间和价格,看看什么是最好的。谢谢!看起来非常接近,但第二个稍微慢一点。生产加速看起来更像是16倍!对查询计时时,请运行两次——第一次运行可能需要从磁盘获取内容;第二个将具有尽可能多的缓存。第二次引用,太棒了!解释告诉我,它仍然选择在名称上使用索引,但在我删除后,它的速度快了大约5倍!:如果你能解释一下你是如何按照索引的顺序查看字段的,那就太好了。名称首先用于GROUP BY子句,然后时间用于每个组中的聚合函数,特别是将改进MAX和MIN函数。出于好奇,你可以交换时间和价格,看看什么是最好的。谢谢!看起来非常接近,但第二个稍微慢一点。生产加速看起来更像是16倍!对查询计时时,请运行两次——第一次运行可能需要从磁盘获取内容;第二个将具有尽可能多的缓存。第二次报价。完全同意99999。简洁的省略。在索引获得巨大收益后,您将查询重写为使用AVG(感谢您指出这一点,doh!)似乎又节省了15%的时间。谢谢完全同意999999。简洁的省略。在索引获得巨大收益后,您将查询重写为使用AVG(感谢您指出这一点,doh!)似乎又节省了15%的时间。谢谢谢谢市场是24小时-魔术卡。名字可以是最长的(“我们的市场调查显示,玩家喜欢很长的牌名,所以我们制作的这张牌是有史以来绝对最长的牌名”),但唯一的子串会更小。有些名字有变音符号。时间戳为“最后一次跑步时间”、“前一周”、“前一个月”和“赛季开始”(固定日期-每季度更改)。对于DOUBLE,我几乎不需要任何精度-小数点后一位?我能在那里存更多吗?存储为某种小整数?我来试试主键。再次感谢!好吧,我做了一个错误的假设。
name
的标准化仍然是明智的。
DECIMAL(7,1)
需要4个字节;你能拥有的最大数量是多少?也可以使用4字节的
FLOAT
,最大值约为10^38.0。虽然这些显然没有获得正确索引的巨大影响,但我确实在本地实现了12.5%的加速。它似乎对目前需要45秒的prod没有多大影响。汇总表仍然合适吗?在深入研究汇总表之前,。。。每个卡名每天有多少行?如果每天有许多,则将每天汇总到一个表中。如果为1/天,则每周和每月单独汇总。你如何定义“季节”?谢谢!市场是24小时-魔术卡。名字可以是最长的(“我们的市场调查显示,玩家喜欢很长的牌名,所以我们制作的这张牌是有史以来绝对最长的牌名”),但唯一的子串会更小。有些名字有变音符号。时间戳为“最后一次跑步时间”、“前一周”、“前一个月”和“赛季开始”(固定日期-每季度更改)。对于DOUBLE,我几乎不需要任何精度-小数点后一位?我能在那里存更多吗?存储为某种小整数?我来试试主键。再次感谢!好吧,我做了一个错误的假设。
name
的标准化仍然是明智的。
DECIMAL(7,1)
需要4个字节;你能拥有的最大数量是多少?也可以使用4字节的
FLOAT
,最大值约为10^38.0。虽然这些显然没有获得正确索引的巨大影响,但我确实在本地实现了12.5%的加速。它似乎对目前需要45秒的prod没有多大影响。汇总表仍然合适吗?在深入研究汇总表之前,。。。每个卡名每天有多少行?如果每天有许多,则将每天汇总到一个表中。如果为1/天,则每周和每月单独汇总。你如何定义“季节”?
INSERT INTO cache (`time`, name, price, low, high, week, month, season)
SELECT
    MAX(`time`) AS `time`,
    name,
    MIN(CASE WHEN `time` = 1500254967 THEN price ELSE 999999 END) AS price,
    MIN(price) AS low,
    MAX(price) AS high,
    SUM(CASE WHEN `time` > 1499650167 AND price = 1 THEN 1 ELSE 0 END) / SUM(CASE WHEN `time` > 1499650167 THEN 1 ELSE 0 END) AS week,
    SUM(CASE WHEN `time` > 1497835767 AND price = 1 THEN 1 ELSE 0 END) / SUM(CASE WHEN `time` > 1497835767 THEN 1 ELSE 0 END) AS month,
    SUM(CASE WHEN `time` > 1499995767 AND price = 1 THEN 1 ELSE 0 END) / SUM(CASE WHEN `time` > 1499995767 THEN 1 ELSE 0 END) AS season
FROM low_price
GROUP BY name;
+----+-------------+-----------+-------+---------------+----------+---------+------+----------+-------+
| id | select_type | table     | type  | possible_keys | key      | key_len | ref  | rows     | Extra |
+----+-------------+-----------+-------+---------------+----------+---------+------+----------+-------+
|  1 | SIMPLE      | low_price | index | idx_name      | idx_name | 603     | NULL | 20875117 | NULL  |
+----+-------------+-----------+-------+---------------+----------+---------+------+----------+-------+
CREATE TABLE `low_price` (
  `time` int(11) DEFAULT NULL,
  `price` int(11) DEFAULT NULL,
  `name` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

CREATE TABLE `cache` (
  `time` int(11) DEFAULT NULL,
  `name` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `high` int(11) DEFAULT NULL,
  `low` int(11) DEFAULT NULL,
  `price` int(11) DEFAULT NULL,
  `week` double DEFAULT NULL,
  `month` double DEFAULT NULL,
  `season` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
name,
time,
price
INSERT INTO cache (`time`, name, price, low, high, week, month, season)
    SELECT MAX(`time`) AS `time`,
           name,
           MIN(CASE WHEN `time` = 1500254967 THEN price END) AS price,
           MIN(price) AS low, MAX(price) AS high,
           AVG(CASE WHEN `time` > 1499650167 AND price = 1 THEN 1.0
                    WHEN `time` > 1499650167 THEN 0
               END) AS week,
           AVG(CASE WHEN `time` > 1497835767 AND price = 1 THEN 1.0
                    WHEN `time` > 1497835767 THEN 0.0
               END) AS month,
           AVG(CASE WHEN `time` > 1499995767 AND price = 1 THEN 1.0
                    WHEN `time` > 1499995767 THEN 0.0
               END) AS season
    FROM low_price
    GROUP BY name;