我对一个有1.23亿条记录的分区表进行了select查询,获取数据需要10分钟以上的时间。我的查询看起来像'select*from tablename where column1='1.1.1.1'order by timestamp desc';表已在第1列上编入索引。
谢谢你的帮助。
(来自评论)
CREATE TABLE mytable (
column1 varchar(256) NOT NULL,
column2 varchar(100) NOT NULL,
column3 smallint(5) unsigned NOT NULL,
column4 smallint(5) unsigned NOT NULL,
timestamp bigint(20) unsigned NOT NULL,
KEY mytable_idx (column2,timestamp,column3,column4),
KEY ip_addr_index (column1),
KEY ts_idx (timestamp)
) /*!50100 PARTITION BY RANGE ((TIMESTAMP))
(PARTITION p1498800000 VALUES LESS THAN (1498800000) ENGINE = InnoDB,
PARTITION p1500000000 VALUES LESS THAN (1500000000) ENGINE = InnoDB,
PARTITION p1501200000 VALUES LESS THAN (1501200000) ENGINE = InnoDB,
PARTITION p1502400000 VALUES LESS THAN (1502400000) ENGINE = InnoDB,
PARTITION p1503600000 VALUES LESS THAN (1503600000) ENGINE = InnoDB,
PARTITION p1504800000 VALUES LESS THAN (1504800000) ENGINE = InnoDB,
PARTITION p1506000000 VALUES LESS THAN (1506000000) ENGINE = InnoDB
) */
2条答案
按热度按时间00jrzges1#
PARTITIONing
本质上不提供速度。请提供SHOW CREATE TABLE
因此,我们可以讨论分区是否会影响您的性能。无论表是否分区,都是最优的。特别是,该索引对非分区的应用同样有效(戈登关于
DESC
对性能没有影响,无论是旧版本还是新版本。)对于1.23亿行,您应该关注数据类型。如果你有
然后,ipv4地址可以从最多17个字节改进为正好4个字节:
有适当的转换
INSERT
以及SELECT
. 做出这样的改变还将允许进行cdr和其他射程测试,这是不可能的VARCHAR
. 您需要处理ipv6吗?我在这里讨论。有多少行匹配
1.1.1.1
? 有吗TEXT
柱?什么是PRIMARY KEY
? 哪个发动机?每一个问题都可能对“10分钟”产生影响。理解“复合”索引何时优于单列索引是很重要的。更多讨论:http://mysql.rjweb.org/doc.php/index_cookbook_mysql
创建后
替换此
具有
在需要分区之前,不要创建多个分区。总是有一个
LESS THAN (MAXVALUE)
分区以防万一。ipv4可以与
VARCHAR(15)
; ipv6适合(39)
或二进制(16)后打包。 对于这一个查询,必须执行7个查询(每个分区一个);结果放在一起,然后排序。如果没有分区,它将变成一个查询,没有排序(因为索引已经排序)。所以,(我相信)分区会减慢查询的速度。 在123m行中讨论性能时,我需要一次查看所有主要查询,以便提供建议。对一个查询进行优化很可能会对另一个查询进行去优化。 似乎没有理由使用
BIGINT为了
TIMESTAMP.
INT UNSIGNED将为每行数据节省4字节,并为索引节省更多字节。可能总共节省了2gb的磁盘空间。这就意味着某些查询的速度有所加快。 如果
timestamp总是用在一个“范围”,那么这个索引
(column2,timestamp,column3,column4)` 可能是在一个低效的秩序。请提供从这个索引中受益的查询,以便我进一步阐述。soat7uwm2#
对于此查询:
你想要索引吗
(column1, timestamp desc)
. 注:以下为desc
在mysql的早期版本中可能会被忽略。