NBh*_*tti 1 mysql performance percona
我在 5.6.35-81.0 Percona Server 上有一个大型 MySQL 表,主键中有间隙。该表有大约 5300 万条记录,自动增量键现在约为 3.7 亿条。该表是电话号码列表,用户添加/删除号码非常频繁,因此 BIGINT 的 PRIMARY 键内部有间隙。
我现在面临的问题是,当我做一个简单的 SELECT * FROM 表时,MySQL 默认不使用 PRIMARY 键对结果进行排序。它使用表中的电话号码字段对数据进行排序,因此数据被按顺序选择,而不是按顺序保存在数据库中。
带有 ORDER BY id 的 Offcourse SELECT 需要很长时间。另一种解决方案是将所有数据复制到另一个表,但这需要应用程序停机。我怎样才能解决这个问题或在未来避免这种情况?
CREATE TABLE `contacts` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`phonebook_id` int(11) NOT NULL,
`campaign_id` int(11) DEFAULT NULL,
`contact` varchar(45) NOT NULL,
`status` tinyint(1) unsigned NOT NULL DEFAULT '1',
`admin` tinyint(1) unsigned NOT NULL DEFAULT '0',
`call_status` tinyint(1) unsigned NOT NULL DEFAULT '1',
`active_call` tinyint(1) unsigned NOT NULL DEFAULT '0',
`test_call` tinyint(1) unsigned NOT NULL DEFAULT '0',
`dnc_contact` tinyint(1) unsigned NOT NULL DEFAULT '0',
`v_node_name` varchar(45) DEFAULT NULL,
`timezone` varchar(4) DEFAULT NULL,
`updated_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_date` timestamp NULL DEFAULT NULL,
`contact_name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `phonebook_id` (`phonebook_id`,`contact`),
KEY `idx_001` (`active_call`,`campaign_id`,`test_call`),
KEY `idx_002` (`phonebook_id`,`call_status`,`test_call`,`campaign_id`,`active_call`,`dnc_contact`),
KEY `idx_003` (`phonebook_id`,`test_call`,`call_status`,`dnc_contact`),
KEY `FK_campaign_id_idx` (`campaign_id`),
KEY `idx_testcall` (`test_call`),
KEY `idx_004` (`campaign_id`,`call_status`,`test_call`),
KEY `idx_active_call` (`active_call`)
) ENGINE=InnoDB AUTO_INCREMENT=2369201 DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)
MySQL
像任何其他 RDBMS 一样,默认情况下不对结果进行排序。您必须添加ORDER BY
子句才能获得有序结果。否则返回的订单行是未定义的。
在某些退化的情况下,您有机会在没有的情况下获得有序结果ORDER BY
- 例如,当您将预排序的行批量插入到新创建的表中时,如果您没有DELETE
或UPDATE
之前没有任何行SELECT
。但是当表很重DELETE
d 或UPDATE
d 时,mysql
执行所谓的“索引树重新平衡”。遍历重新平衡的索引树以不可预测的顺序返回行。因此,您永远不应该依赖于没有ORDER BY
返回有序结果的查询的假设。