use*_*477 5 mysql optimization order-by
过去两天我一直为此而头疼。
CREATE TABLE `clients` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`guarantor_name` varchar(50) NOT NULL,
`guarantor_dob` date DEFAULT NULL,
`guarantor_relationship` int(11) DEFAULT '14',
`telephone_number` varchar(50) DEFAULT NULL,
`telephone_type` int(11) DEFAULT '7',
`state` varchar(50) DEFAULT '',
`pincode` mediumint(6) unsigned NOT NULL,
`income` int(11) DEFAULT NULL,
`family_income` int(11) DEFAULT NULL,
`name` varchar(100) NOT NULL,
`gender` int(11) DEFAULT '2',
`marital_status` int(11) DEFAULT '1',
`reference` varchar(100) DEFAULT NULL,
`reference_type` int(11) DEFAULT '4',
`reference2` varchar(50) DEFAULT NULL,
`reference2_type` int(11) DEFAULT '2',
`spouse_name` varchar(100) DEFAULT NULL,
`date_of_birth` date DEFAULT NULL,
`spouse_date_of_birth` date DEFAULT NULL,
`address` text NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
`inactive_reason` int(11) DEFAULT '1',
`date_joined` date DEFAULT NULL,
`grt_pass_date` date DEFAULT NULL,
`center_id` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT '2013-01-06 14:29:16',
`deleted_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`deceased_on` date DEFAULT NULL,
`created_by_user_id` int(11) NOT NULL,
`other_income` int(11) DEFAULT NULL,
`total_income` int(11) DEFAULT NULL,
`poverty_status` varchar(10) DEFAULT NULL,
`caste` int(11) DEFAULT '1',
`religion` int(11) DEFAULT '1',
`created_by_staff_member_id` int(11) NOT NULL,
`claim_document_status` int(11) DEFAULT '1',
`claim_document_recieved_by` int(11) DEFAULT NULL,
`cliam_document_recieved_on` date DEFAULT NULL,
`town_classification` int(11) DEFAULT '1',
`upload_reference` int(11) DEFAULT NULL,
`picture_file_name` varchar(50) DEFAULT NULL,
`picture_content_type` varchar(50) DEFAULT NULL,
`picture_file_size` int(11) DEFAULT NULL,
`picture_updated_at` datetime DEFAULT NULL,
`application_form_file_name` varchar(50) DEFAULT NULL,
`application_form_content_type` varchar(50) DEFAULT NULL,
`application_form_file_size` int(11) DEFAULT NULL,
`application_form_updated_at` datetime DEFAULT NULL,
`fingerprint_file_name` varchar(50) DEFAULT NULL,
`fingerprint_content_type` varchar(50) DEFAULT NULL,
`fingerprint_file_size` int(11) DEFAULT NULL,
`fingerprint_updated_at` datetime DEFAULT NULL,
`client_group_id` int(10) unsigned DEFAULT NULL,
`priority_sector_list_id` int(10) unsigned DEFAULT NULL,
`upload_id` int(10) unsigned DEFAULT NULL,
`psl_sub_category_id` int(10) unsigned DEFAULT NULL,
`occupation_id` int(10) unsigned DEFAULT NULL,
`client_identifier` varchar(50) NOT NULL,
`age` int(11) DEFAULT NULL,
`age_as_on_date` date DEFAULT NULL,
`is_loan_applicant` tinyint(1) DEFAULT '0',
`occupation_field` varchar(50) DEFAULT NULL,
`father_name` varchar(100) DEFAULT NULL,
`father_dob` date DEFAULT NULL,
`ews` int(11) DEFAULT '1',
`residence_stability` int(11) DEFAULT '1',
`owner_status` int(11) DEFAULT '1',
`no_of_children` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_clients_client_group` (`client_group_id`),
KEY `index_clients_psl_sub_category` (`psl_sub_category_id`),
KEY `index_dedupe_variables`
(`deleted_at`,`state`,`reference_type`,`reference`,`id`,`client_identifier`)
) ENGINE=InnoDB AUTO_INCREMENT=234631 DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
这是桌子。嗯,这是一张很长的桌子。现在我有查询
SELECT SQL_NO_CACHE `id`, `client_identifier`, `guarantor_name`, `guarantor_dob`,
`guarantor_relationship`, `telephone_number`, `telephone_type`, `state`, `pincode`,
`income`, `family_income`, `name`, `gender`, `marital_status`, `reference`,
`reference_type`, `reference2`, `reference2_type`, `father_name`, `father_dob`,
`ews`, `residence_stability`, `owner_status`, `no_of_children`, `spouse_name`, `age`,
`age_as_on_date`, `date_of_birth`, `spouse_date_of_birth`, `active`, `inactive_reason`,
`date_joined`, `grt_pass_date`, `center_id`, `created_at`, `updated_at`, `deceased_on`,
`created_by_user_id`, `other_income`, `total_income`, `poverty_status`, `caste`,
`religion`, `created_by_staff_member_id`, `claim_document_status`,
`claim_document_recieved_by`, `cliam_document_recieved_on`, `town_classification`,
`is_loan_applicant`, `occupation_field`, `upload_reference`, `picture_file_name`,
`picture_content_type`, `picture_file_size`, `picture_updated_at`,
`application_form_file_name`, `application_form_content_type`,
`application_form_file_size`, `application_form_updated_at`,
`fingerprint_file_name`, `fingerprint_content_type`, `fingerprint_file_size`,
`fingerprint_updated_at`, `priority_sector_list_id`, `occupation_id`,
`client_group_id`, `upload_id`, `psl_sub_category_id`
FROM `clients` use index(primary,index_dedupe_variables)
WHERE `deleted_at` IS NULL AND state = 'Maharashtra'
and reference_type = 4 and reference LIKE '%8858' ORDER BY id;
Run Code Online (Sandbox Code Playgroud)
我已经创建了索引
(deleted_at,state,reference_type,reference,id)
Run Code Online (Sandbox Code Playgroud)
当我解释这个查询时,我得到
** * ** * ** * ** * * 1. 行* ** * ** * ** * ** *
d id: 1
select_type: SIMPLE
table: clients
type: ref
possible_keys: index_dedupe_variables
key: index_dedupe_variables
key_len: 167
ref:const、const、const
行:119122
额外:使用 where;
在集合中使用文件排序1 行(0.00 秒)
我尝试增加排序缓冲区大小以及 max_heap_table_size 但我无法摆脱 filesort 但没有用。我什至试图强制索引也不起作用。我想使用覆盖索引,但考虑到列数可能听起来很糟糕。我不确定我哪里出错了:(。
KEY `index_dedupe_variables`
(`deleted_at`,`state`,`reference_type`,`reference`,`id`,`client_identifier`)
Run Code Online (Sandbox Code Playgroud)
尝试删除该索引并将其替换为以下索引:
KEY `new_index`
(`deleted_at`,`state`,`reference_type`,`id`)
Run Code Online (Sandbox Code Playgroud)
即使在使用索引时,也仅使用索引的有用部分;该索引不考虑无法使用索引的第一个实例右侧的列。
在查询中, 'reference'
在左侧使用通配符,使得索引的该列无用,并消除了索引中“id”的使用。
您的解释计划告诉您正在发生这种情况:
ref: const,const,const
Run Code Online (Sandbox Code Playgroud)
由此,您可以看出查询实际上仅使用索引的前三列。
通过重新定义索引以消除不可用的“引用”列,我们可以使用索引的所有 4 列,并且由于索引已经按照您想要的顺序排序,因此我们可以这样做:
WHERE `deleted_at` IS NULL
AND state = 'Maharashtra'
AND reference_type = 4
AND reference LIKE '%8858'
ORDER BY deleted_at, state, reference_type, id
Run Code Online (Sandbox Code Playgroud)
我们并不真的希望它们按前三列排序,但由于它们都是相等比较,因此按它们排序不会改变结果,并且对于优化器来说应该“显而易见”,它可以简单地返回结果索引顺序...不需要文件排序。
您EXPLAIN
应该更改为“使用位置”,并且可能更改为“使用索引”(因为这可能意味着“使用索引进行查找”,即使它不是覆盖索引。)
即使您只有“id”,优化器也可能会流行并且不使用文件排序,ORDER BY
因此您可以在更改索引后尝试两种方式。
另外,从您的查询中删除use index
。不应该需要它。
归档时间: |
|
查看次数: |
1034 次 |
最近记录: |