Mysql

使用 LIMIT 1 優化 MAX 或 ORDER BY 列 DESC

  • February 7, 2018

我有一個場景,我需要插入一條新記錄並增加一個子 ID。查詢很慢。有沒有更好的解決方案?

桌子

CREATE TABLE `link_` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `duid` bigint(20) DEFAULT NULL,
 `domain_id` int(11) DEFAULT NULL
 PRIMARY KEY (`id`),
 KEY `domain_id` (`domain_id`),
 KEY `duid` (`duid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

解決方案 1

INSERT INTO link_ (duid, domain_id)
SELECT
   IFNULL(MAX(duid), 0) + 1 AS duid, 5
FROM
link_
WHERE domain_id = 5;

解決方案 2

INSERT INTO link_ (duid, domain_id)
SELECT
   IFNULL(duid, 0) + 1 AS duid, 5
FROM
   link_
WHERE domain_id = 5
ORDER BY duid DESC
LIMIT 1;

你可能需要重新設計這張桌子,但我想你會喜歡這樣做的。為什麼 ???

你知道 MyISAM 支持將 auto_increment id 分組到 key 嗎?

MySQL 文件中使用 auto_increment 的子標題下MyISAM Notes

對於 MyISAM 表,您可以在多列索引中的輔助列上指定 AUTO_INCREMENT。在這種情況下,AUTO_INCREMENT 列的生成值計算為 MAX(auto_increment_column) + 1 WHERE prefix=given-prefix。當您要將數據放入有序組時,這很有用。

MyISAM 將完成所有繁重的工作,du_id為每個人分配下一個domain_id

我之前討論過幾次

如何使用它

將表格的設計更改為如下所示:

CREATE TABLE `link_` (
 `duid` bigint(20) NOT NULL AUTO_INCREMENT,
 `domain_id` int(11) NOT NULL,
 PRIMARY KEY (`domain_id`,`du_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

您將消除id(每行節省 8 個字節)並刪除不必要的索引。

然後,您的 INSERT 將如下所示:

INSERT INTO link_ (domain_id) VALUES (5);

就是這樣 !!!所有 auto_increment 的東西都是為你處理的!!!

請查看我提到的範常式式碼

試一試 !!!

引用自:https://dba.stackexchange.com/questions/197221