非集群环境中mysql选择分区表的查询优化

时间:2018-07-10 23:26:14

标签: mysql performance partition

我对具有1.23亿条记录的分区表进行了选择查询,这需要10分钟以上的时间来获取数据。我的查询看起来像是'select * from tableName where column1 ='1.1.1.1'按时间戳desc排序”; 该表已在column1上建立索引。

任何帮助表示赞赏。

(来自评论)

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 个答案:

答案 0 :(得分:0)

对于此查询:

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

您要在(column1, timestamp desc)上建立索引。注意:desc在MySQL的早期版本中可能会被忽略。

答案 1 :(得分:0)

PARTITIONing本质上不提供速度。请提供SHOW CREATE TABLE,以便我们讨论您的情况下分区是否确实损害性能。

INDEX(column1, timestamp)  -- In this order

对于表是否分区都是最佳的。特别是,该索引对于未分区的索引同样有效。 (无论是旧版本还是新版本,戈登对DESC的评论都不会影响性能。)

对于1.23亿行,您应该关注数据类型。如果有

column1 VARCHAR(15) CHARACTER SET utf8

然后ipv4_address可以从最多17个字节提高到恰好4个字节:

BINARY(4)

INSERTSELECT上进行适当的转换。进行此更改还可以进行CDR和其他范围测试,而VARCHAR则无法实现。您需要处理IPv6吗?我讨论了here

有多少行与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)或`BINARY(16)中。

对于一个查询,必须完成7个查询(每个分区一个);结果放在一起,然后排序。如果不进行分区,它将成为一个查询,没有排序(因为索引已经排序)。因此,(我相信)分区会降低查询速度

在讨论1.23亿行的性能时,我需要一次查看所有主要查询以提供建议。针对一个查询进行优化可能会针对其他查询进行优化。

似乎没有理由将BIGINT用于TIMESTAMPINT UNSIGNED将为每行数据节省4个字节,再为索引节省更多。也许总共可以节省2GB的磁盘空间。这意味着 some 查询的速度有所提高。

如果timestamp始终在“范围”内使用,则该索引(column2,timestamp,column3,column4)可能 的效率低下。请提供受益于该索引的查询,以便我进一步阐述。