非集群环境下分区表的性能mysql select查询优化

zbdgwd5y  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(319)

我对一个有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
                          ) */
00jrzges

00jrzges1#

PARTITIONing 本质上不提供速度。请提供 SHOW CREATE TABLE 因此,我们可以讨论分区是否会影响您的性能。

INDEX(column1, timestamp)  -- In this order

无论表是否分区,都是最优的。特别是,该索引对非分区的应用同样有效(戈登关于 DESC 对性能没有影响,无论是旧版本还是新版本。)
对于1.23亿行,您应该关注数据类型。如果你有

column1 VARCHAR(15) CHARACTER SET utf8

然后,ipv4地址可以从最多17个字节改进为正好4个字节:

BINARY(4)

有适当的转换 INSERT 以及 SELECT . 做出这样的改变还将允许进行cdr和其他射程测试,这是不可能的 VARCHAR . 您需要处理ipv6吗?我在这里讨论。
有多少行匹配 1.1.1.1 ? 有吗 TEXT 柱?什么是 PRIMARY KEY ? 哪个发动机?每一个问题都可能对“10分钟”产生影响。
理解“复合”索引何时优于单列索引是很重要的。更多讨论:http://mysql.rjweb.org/doc.php/index_cookbook_mysql
创建后
替换此

KEY ip_addr_index (column1)

具有

KEY ip_addr_index (column1, timestamp)

在需要分区之前,不要创建多个分区。总是有一个 LESS THAN (MAXVALUE) 分区以防万一。
ipv4可以与 VARCHAR(15) ; ipv6适合 (39)二进制(16)后打包。 对于这一个查询,必须执行7个查询(每个分区一个);结果放在一起,然后排序。如果没有分区,它将变成一个查询,没有排序(因为索引已经排序)。所以,(我相信)分区会减慢查询的速度。 在123m行中讨论性能时,我需要一次查看所有主要查询,以便提供建议。对一个查询进行优化很可能会对另一个查询进行去优化。 似乎没有理由使用BIGINT为了TIMESTAMP.INT UNSIGNED将为每行数据节省4字节,并为索引节省更多字节。可能总共节省了2gb的磁盘空间。这就意味着某些查询的速度有所加快。 如果timestamp总是用在一个“范围”,那么这个索引(column2,timestamp,column3,column4)` 可能是在一个低效的秩序。请提供从这个索引中受益的查询,以便我进一步阐述。

soat7uwm

soat7uwm2#

对于此查询:

select *
from tableName
where column1 = '1.1.1.1'
order by timestamp desc;

你想要索引吗 (column1, timestamp desc) . 注:以下为 desc 在mysql的早期版本中可能会被忽略。

相关问题