私は 'map_item'のユーザー検索に使用される非常に大きなクエリを持っています。多くの左結合による単純なクエリの最適化
'map_item'には合計5399個のレコードがあり、結合されたテーブルのデータはまったく多くありません。
左の結合なしでこのクエリを実行すると(SELECT map_item_name FROM map_item
)、期待通りに0.00sで返されますが、結合による上記のクエリは約10.00sかかります。
ユーザーは検索に適用できるフィルタが異なるため、クエリにはすべての左結合が必要ですが、元のクエリは実行に長時間(20秒程度)かかっていましたが、クエリのほとんどの部分は上記のまま残されていましたが(これはちょうど左の結合です)、これでも18秒かかります。ここで
は、クエリからの説明文です:
+----+-------------+-------------------+--------+----------------------------------+----------------------------------+---------+-----------------------------------------------------------+------+-----------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------------+--------+----------------------------------+----------------------------------+---------+-----------------------------------------------------------+------+-----------------------------------------------------------------+
| 1 | SIMPLE | map_item | ALL | NULL | NULL | NULL | NULL | 5455 | NULL |
| 1 | SIMPLE | map_section_item | index | NULL | map_section_item_section_id | 8 | NULL | 5330 | Using where; Using index; Using join buffer (Block Nested Loop) |
| 1 | SIMPLE | map_section | eq_ref | PRIMARY | PRIMARY | 4 | bestmeal.map_section_item.map_section_item_section_id | 1 | NULL |
| 1 | SIMPLE | map_item_flag | ALL | NULL | NULL | NULL | NULL | 1509 | Using where; Using join buffer (Block Nested Loop) |
| 1 | SIMPLE | flag | eq_ref | PRIMARY | PRIMARY | 4 | bestmeal.map_item_flag.map_item_flag_flag_id | 1 | Using index |
| 1 | SIMPLE | map | eq_ref | PRIMARY | PRIMARY | 4 | bestmeal.map_section.map_section_map_id | 1 | Using index |
| 1 | SIMPLE | place_map | index | NULL | branch_map_branch_id | 8 | NULL | 1275 | Using where; Using index; Using join buffer (Block Nested Loop) |
| 1 | SIMPLE | place | eq_ref | PRIMARY | PRIMARY | 4 | bestmeal.place_map.place_map_place_id | 1 | NULL |
| 1 | SIMPLE | place_category | ref | place_category_place_id | place_category_place_id | 4 | bestmeal.place.place_id | 1 | Using index |
| 1 | SIMPLE | category | eq_ref | PRIMARY | PRIMARY | 4 | bestmeal.place_category.place_category_category_id | 1 | Using index |
| 1 | SIMPLE | review | ref | review_map_item_id | review_map_item_id | 4 | bestmeal.map_item.map_item_id | 1 | Using index |
| 1 | SIMPLE | map_price | ref | map_price_item_id | map_price_item_id | 4 | bestmeal.map_item.map_item_id | 1 | Using index |
| 1 | SIMPLE | county_list | eq_ref | PRIMARY | PRIMARY | 4 | bestmeal.place.place_address_county | 1 | Using index |
+----+-------------+-------------------+--------+----------------------------------+----------------------------------+---------+-----------------------------------------------------------+------+-----------------------------------------------------------------+
これらのすべては、インデックスフィールドに対して行われた結合、および結合されたテーブルのいずれの代わりに使用することができ、それらのいずれかの不要なインデックスを持っていません意図するインデックス
私はクエリの最適化について専門家ではありませんが、私は左の結合を維持しながらこのクエリを高速化するためにできることを考え出すのには苦労しています。私はまた、実際に結合を使用せずに同じ結果を返す代替ソリューションを考えることはできません。
このクエリのパフォーマンスを向上させるのに役立つアイデアや、より速く、より速い方法でユーザーの検索を達成するためのアイデアはありますか?
編集要求されるように 表構造:これらの行で
CREATE TABLE `map_item` (
`map_item_id` int(11) NOT NULL AUTO_INCREMENT,
`map_item_account_id` int(11) NOT NULL DEFAULT '0',
`map_item_category_id` int(11) NOT NULL,
`map_item_name` varchar(255) DEFAULT NULL,
`map_item_description` text,
`map_item_tags` varchar(255) DEFAULT NULL,
`map_item_type` set('d','f') DEFAULT NULL,
PRIMARY KEY (`map_item_id`),
KEY `map_item_account_id` (`map_item_account_id`),
KEY `map_item_tags` (`map_item_tags`),
KEY `map_item_category_id` (`map_item_category_id`),
FULLTEXT KEY `map_item_keyword_search` (`map_item_name`,`map_item_description`,`map_item_tags`),
FULLTEXT KEY `map_item_name` (`map_item_name`),
FULLTEXT KEY `map_item_description` (`map_item_description`),
FULLTEXT KEY `map_item_tags_2` (`map_item_tags`)
) ENGINE=InnoDB AUTO_INCREMENT=5420 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `map_section_item` (
`map_section_item_id` int(11) NOT NULL AUTO_INCREMENT,
`map_section_item_section_id` int(11) NOT NULL DEFAULT '0',
`map_section_item_item_id` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`map_section_item_id`),
KEY `map_section_item_section_id` (`map_section_item_section_id`,`map_section_item_item_id`)
) ENGINE=InnoDB AUTO_INCREMENT=24410 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `map_section` (
`map_section_id` int(11) NOT NULL AUTO_INCREMENT,
`map_section_map_id` int(11) NOT NULL DEFAULT '0',
`map_section_map_draft_id` int(11) NOT NULL DEFAULT '0',
`map_section_column` tinyint(1) NOT NULL DEFAULT '1',
`map_section_name` varchar(255) DEFAULT NULL,
`map_section_description` text,
PRIMARY KEY (`map_section_id`),
KEY `map_section_map_draft_id` (`map_section_map_draft_id`),
KEY `map_section_map_id` (`map_section_map_id`),
FULLTEXT KEY `index_name` (`map_section_name`)
) ENGINE=InnoDB AUTO_INCREMENT=4254 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `map_item_flag` (
`map_item_flag_id` int(11) NOT NULL AUTO_INCREMENT,
`map_item_flag_item_id` int(11) NOT NULL DEFAULT '0',
`map_item_flag_flag_id` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`map_item_flag_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1547 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `flag` (
`flag_id` int(11) NOT NULL AUTO_INCREMENT,
`flag_category_id` int(11) NOT NULL DEFAULT '0',
`flag_name` varchar(255) DEFAULT NULL,
`flag_description` varchar(255) DEFAULT NULL,
`flag_img` varchar(255) DEFAULT NULL,
`flag_order` tinyint(2) NOT NULL DEFAULT '0',
PRIMARY KEY (`flag_id`),
KEY `flag_category_id` (`flag_category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `map` (
`map_id` int(11) NOT NULL AUTO_INCREMENT,
`map_account_id` int(11) NOT NULL DEFAULT '0',
`map_name` varchar(255) DEFAULT NULL,
`map_description` text,
`map_type` set('d','f') DEFAULT NULL,
`map_layout` set('columns','tabs','collapsed') DEFAULT NULL,
PRIMARY KEY (`map_id`),
KEY `map_account_id` (`map_account_id`)
) ENGINE=InnoDB AUTO_INCREMENT=138 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `place_map` (
`place_map_id` int(11) NOT NULL AUTO_INCREMENT,
`place_map_place_id` int(11) NOT NULL DEFAULT '0',
`place_map_map_id` int(11) NOT NULL DEFAULT '0',
`place_map_active` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`place_map_id`),
KEY `branch_map_branch_id` (`place_map_place_id`,`place_map_map_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2176 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `place` (
`place_id` int(11) NOT NULL AUTO_INCREMENT,
`place_account_id` int(11) NOT NULL DEFAULT '0',
`place_name` varchar(120) DEFAULT NULL,
`place_alias` varchar(255) DEFAULT NULL,
`place_description` text,
`place_address_line_one` varchar(100) DEFAULT NULL,
`place_address_line_two` varchar(100) DEFAULT NULL,
`place_address_line_three` varchar(100) DEFAULT NULL,
`place_address_town` varchar(100) DEFAULT NULL,
`place_address_county` int(11) NOT NULL DEFAULT '0',
`place_address_postcode` varchar(10) DEFAULT NULL,
`place_address_latitude` decimal(11,8) DEFAULT NULL,
`place_address_longitude` decimal(11,8) DEFAULT NULL,
`place_phone` varchar(20) DEFAULT NULL,
`place_email` varchar(255) DEFAULT NULL,
`place_website` varchar(120) DEFAULT NULL,
`place_flag_initial_email` tinyint(1) NOT NULL DEFAULT '0',
`place_audit_admin_id` int(11) NOT NULL DEFAULT '0',
`place_last_audit_datetime` datetime DEFAULT NULL,
`place_created_by_admin_id` int(11) NOT NULL DEFAULT '0',
`place_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`place_tried_google` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`place_id`),
KEY `place_account_id` (`place_account_id`),
KEY `place_address_county` (`place_address_county`),
KEY `place_alias` (`place_alias`),
KEY `place_audit_admin_id` (`place_audit_admin_id`),
KEY `place_created_by_admin_id` (`place_created_by_admin_id`),
FULLTEXT KEY `place_name` (`place_name`),
FULLTEXT KEY `place_keyword_search` (`place_name`,`place_address_town`),
FULLTEXT KEY `place_address_town` (`place_address_town`)
) ENGINE=InnoDB AUTO_INCREMENT=135167 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `place_category` (
`place_category_id` int(11) NOT NULL AUTO_INCREMENT,
`place_category_place_id` int(11) NOT NULL DEFAULT '0',
`place_category_category_id` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`place_category_id`),
UNIQUE KEY `place_category_place_id` (`place_category_place_id`,`place_category_category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=208987 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `category` (
`category_id` int(11) NOT NULL AUTO_INCREMENT,
`category_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=168 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `review` (
`review_id` int(11) NOT NULL AUTO_INCREMENT,
`review_user_id` int(11) NOT NULL DEFAULT '0',
`review_place_id` int(11) NOT NULL DEFAULT '0',
`review_map_item_id` int(11) NOT NULL DEFAULT '0',
`review_otm_item_name` varchar(156) DEFAULT NULL,
`review_headline` varchar(255) DEFAULT NULL,
`review_message` text,
`review_rating` tinyint(1) NOT NULL DEFAULT '0',
`review_datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`review_edited_datetime` datetime DEFAULT NULL,
`review_hidden` tinyint(1) NOT NULL DEFAULT '0',
`review_deleted` tinyint(1) NOT NULL DEFAULT '0',
`review_status` set('pending','published','hidden','deleted') NOT NULL,
PRIMARY KEY (`review_id`),
KEY `review_map_item_id` (`review_map_item_id`),
KEY `review_place_id` (`review_place_id`),
KEY `review_user_id` (`review_user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `map_price` (
`map_price_id` int(11) NOT NULL AUTO_INCREMENT,
`map_price_item_id` int(11) NOT NULL DEFAULT '0',
`map_price_label` varchar(50) DEFAULT NULL,
`map_price_value` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`map_price_id`),
KEY `map_price_item_id` (`map_price_item_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5872 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
CREATE TABLE `county_list` (
`county_id` int(11) NOT NULL AUTO_INCREMENT,
`county_country_id` int(11) NOT NULL DEFAULT '0',
`county_name` varchar(120) DEFAULT NULL,
`county_alias` varchar(120) DEFAULT NULL,
PRIMARY KEY (`county_id`),
KEY `county_alias` (`county_alias`),
KEY `county_country_id` (`county_country_id`)
) ENGINE=InnoDB AUTO_INCREMENT=142 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
インデックスはありますか? –
IDフィールドのデータ型としてINTを使用していることを確認し、それらの外部キーにインデックスを作成してください。 – Lamar
申し訳ありませんが、私は元の投稿に言及すべきでした。すべての結合は、索引付きフィールドで結合されます。この問合せで使用される表には、不要な索引はありません。 – Ryan