【问题标题】:MySQL - ORDER BY and LIMIT performance on large tableMySQL - 大表上的 ORDER BY 和 LIMIT 性能
【发布时间】:2014-06-21 09:45:31
【问题描述】:

以下 SQL 查询的平均持续时间为 100 秒

SELECT id FROM members WHERE boolean_deleted = 0 ORDER BY company_name ASC LIMIT 3045700, 25

该表有 300 万 条记录。

为 boolean_deleted 和 company_name 列设置了 索引

如何优化这个 SQL 查询?

解释:

id: 1
select_type: SIMPLE
table: members
type: range
possible_keys: boolean_deleted
key: boolean_deleted
key_len: 1
ref:
rows: 3045758
Extra: Using where; Using file sort

表结构:

-- ----------------------------
--  Table structure for `members`
-- ----------------------------
DROP TABLE IF EXISTS `members`;
CREATE TABLE `members` (
    `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `creator_id` int(11) UNSIGNED NOT NULL,
    `number` varchar(255) DEFAULT NULL,
    `type` enum('Zakelijk','Prive','Onbekend') NOT NULL DEFAULT 'Onbekend',
    `company_name` varchar(50) NOT NULL,
    `primary_contact` int(11) UNSIGNED NOT NULL,
    `primary_address` int(11) UNSIGNED NOT NULL,
    `primary_bankaccount` int(11) UNSIGNED NOT NULL,
    `market` varchar(255) NOT NULL,
    `awp_klasse` enum('Onbekend','Geen','1','2-4','5-9','10-19','20-49','50-99','100-199','200-499','500-749','750-999','>1000') DEFAULT 'Onbekend',
    `awp_reeel` int(11) UNSIGNED DEFAULT 0,
    `vatnumber` varchar(15) NOT NULL COMMENT 'BTW nummer',
    `ccnumber` varchar(15) NOT NULL COMMENT 'KVK nummer',
    `rsin_number` varchar(15) DEFAULT NULL COMMENT 'Rechtspersonen Samenwerkingsverbanden Informatie Nummer',
    `establishment_number` varchar(25) DEFAULT NULL COMMENT 'Vestigingsnummer kamer',
    `rvm` enum('Onbekend','Buitenlandse onderneming','Besloten Vennootschap','Cooperatieve Vereniging','Commanditaire Vennootschap','Eenmanszaak','Maatschap','Naamloze Vennootschap','Onderlinge Waarborgmaatschappij','Rederij','Stichting','Vereniging','Vennootschap Onder Firma','Europees Economisch Samenwerkingsverband','EG-vennootschap met onderneming in Nederland','EG-vennootschap met Hoofdnederzetting in Nederland','Semi EG-vennootschap met onderneming in Nederland','Semi EG-vennootschap met Hoofdnederzetting in Ned.','Nevenvestiging met vestiging buiten Nederland','Geen rechtsvorm (overheid etc.)','Rechtspersoon in oprichting','Kerkgenootschap','Overige rechtsvormen','Openbare Vennootschap','Europese Naamloze Vennootschap','Vereniging van Eigenaars','Publieksrechtelijke rechtspersoon','Privaatrechtelijke rechtspersoon') DEFAULT 'Onbekend' COMMENT 'Rechtsvorm',
    `sbi` varchar(255) DEFAULT NULL COMMENT 'De Standaard Bedrijfsindeling',
    `sideline_activities_1` varchar(255) DEFAULT NULL COMMENT 'Neven omschrijving',
    `sideline_activities_2` varchar(255) DEFAULT NULL COMMENT 'Neven omschrijving',
    `status` enum('Opgeheven','Failliet','Mailstop','Neutraal','Surseance van betaling','Wet Schuldsanering Natuurlijke Personen') NOT NULL DEFAULT 'Neutraal' COMMENT 'Graydon',
    `boolean_deleted` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
    `boolean_member` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
    `date_created` datetime NOT NULL,
    `reason_of_deletion` text NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `creator_id` (`creator_id`) comment '',
    INDEX `boolean_deleted` (`boolean_deleted`) comment '',
    INDEX `type` (`type`) comment '',
    INDEX `primary_contact` (`primary_contact`) comment '',
    INDEX `primary_address` (`primary_address`) comment '',
    INDEX `primary_bankaccount` (`primary_bankaccount`) comment '',
    INDEX `ccnumber` (`ccnumber`) comment '',
    INDEX `company_name` (`company_name`) comment '',
    FULLTEXT `search_company_name` (`company_name`) comment '',
    FULLTEXT `search_ccnumber` (`ccnumber`) comment ''
) ENGINE=`MyISAM` AUTO_INCREMENT=3045765 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT=DYNAMIC COMMENT='' CHECKSUM=0 DELAY_KEY_WRITE=0;

【问题讨论】:

    标签: mysql sql-order-by limit myisam


    【解决方案1】:

    对于此查询,您需要在您过滤的列和您排序的列上方有一个索引。朝着这个方向。

    在你的情况下:

         INDEX `yourindexname` (`boolean_deleted`, `company_name`)
    

    如果它有效,“使用文件排序”不应再显示在您的解释结果中。

    【讨论】:

    • 在组合索引中首先选择哪一列似乎很重要。你是对的,“使用文件排序”不再被使用了! SQL 查询现在的平均持续时间为 10 秒。这可以进一步优化吗?
    • 一种可能性。如果您仅将此查询用于选择 id,则可以使用覆盖索引对其进行测试。这意味着查询中所有使用的列都包含在索引中。我认为INDEX yourindexname (boolean_deleted, company_name, id) 看看:mysql glossary
    • 我终于发现索引中列的正确顺序应该是 boolean_deleted、company_name 和 id。但我仍然想知道为什么... SQL 查询现在的平均持续时间为 3 秒
    猜你喜欢
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 2016-01-19
    • 1970-01-01
    相关资源
    最近更新 更多