MySQL 默认不使用 PRIMARY KEY 进行排序

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)

Kon*_*bas 6

MySQL像任何其他 RDBMS 一样,默认情况下不对结果进行排序。您必须添加ORDER BY子句才能获得有序结果。否则返回的订单行是未定义的。

在某些退化的情况下,您有机会在没有的情况下获得有序结果ORDER BY- 例如,当您将预排序的行批量插入到新创建的表中时,如果您没有DELETEUPDATE之前没有任何行SELECT。但是当表很重DELETEd 或UPDATEd 时,mysql执行所谓的“索引树重新平衡”。遍历重新平衡的索引树以不可预测的顺序返回行。因此,您永远不应该依赖于没有ORDER BY返回有序结果的查询的假设。

  • 这个答案假设 InnoDB。MyISAM 的工作方式不同。涉及哪个引擎? (2认同)