我对具有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
) */
答案 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)
在INSERT
和SELECT
上进行适当的转换。进行此更改还可以进行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
用于TIMESTAMP
。 INT UNSIGNED
将为每行数据节省4个字节,再为索引节省更多。也许总共可以节省2GB的磁盘空间。这意味着 some 查询的速度有所提高。
如果timestamp
始终在“范围”内使用,则该索引(column2,timestamp,column3,column4)
可能 的效率低下。请提供受益于该索引的查询,以便我进一步阐述。