下面的查询,使用CakePHP的i18n表,需要大约1000毫秒才能运行。我的i18n表很大 - 它有大约600,000行。根据Cake架构,我在此表上有默认索引。
如何加快这样的查询速度?我在可能的情况下缓存它们,但是当需要清除缓存时,这些查询会被运行,并且它们会显着降低性能。
SELECT `Category`.`id`, `Category`.`slug`, `Category`.`name`, `Category`.`description`, `Category`.`head_title`, `Category`.`display_title`, `Category`.`category_count`, `Category`.`product_count`, `Category`.`parent_id`, `Category`.`lft`, `Category`.`rght`, `Category`.`sort_order`, `Category`.`created`, `Category`.`modified`, `Category`.`image_processed`, ((rght - lft) = 1) AS `Category__is_child`, (`I18n__name`.`content`) AS `Category__i18n_name`, (`I18n__description`.`content`) AS `Category__i18n_description`, (`I18n__slug`.`content`) AS `Category__i18n_slug`, (`I18n__head_title`.`content`) AS `Category__i18n_head_title`, (`I18n__meta_description`.`content`) AS `Category__i18n_meta_description`, (`I18n__heading_title`.`content`) AS `Category__i18n_heading_title` FROM `fracmerl_dev`.`categories` AS `Category`
INNER JOIN `fracmerl_dev`.`i18n` AS `I18n__name`
ON (`Category`.`id` = `I18n__name`.`foreign_key`
AND `I18n__name`.`model` = 'Category'
AND `I18n__name`.`field` = 'name'
AND `I18n__name`.`locale` = 'eng')
INNER JOIN `fracmerl_dev`.`i18n` AS `I18n__description`
ON (`Category`.`id` = `I18n__description`.`foreign_key`
AND `I18n__description`.`model` = 'Category'
AND `I18n__description`.`field` = 'description'
AND `I18n__description`.`locale` = 'eng')
INNER JOIN `fracmerl_dev`.`i18n` AS `I18n__slug`
ON (`Category`.`id` = `I18n__slug`.`foreign_key`
AND `I18n__slug`.`model` = 'Category'
AND `I18n__slug`.`field` = 'slug'
AND `I18n__slug`.`locale` = 'eng')
INNER JOIN `fracmerl_dev`.`i18n` AS `I18n__head_title`
ON (`Category`.`id` = `I18n__head_title`.`foreign_key`
AND `I18n__head_title`.`model` = 'Category'
AND `I18n__head_title`.`field` = 'head_title'
AND `I18n__head_title`.`locale` = 'eng')
INNER JOIN `fracmerl_dev`.`i18n` AS `I18n__meta_description`
ON (`Category`.`id` = `I18n__meta_description`.`foreign_key`
AND `I18n__meta_description`.`model` = 'Category'
AND `I18n__meta_description`.`field` = 'meta_description'
AND `I18n__meta_description`.`locale` = 'eng')
INNER JOIN `fracmerl_dev`.`i18n` AS `I18n__heading_title`
ON (`Category`.`id` = `I18n__heading_title`.`foreign_key`
AND `I18n__heading_title`.`model` = 'Category'
AND `I18n__heading_title`.`field` = 'heading_title'
AND `I18n__heading_title`.`locale` = 'eng')
WHERE `I18n__slug`.`content` = 'category-slug'
ORDER BY `Category`.`sort_order` ASC, `Category`.`name` ASC
LIMIT 1
编辑 - 索引,SHOW INDEX FROM i18n
i18n 0 PRIMARY 1 id A 598455 NULL NULL BTREE
i18n 1 locale 1 locale A 5 NULL NULL BTREE
i18n 1 model 1 model A 3 NULL NULL BTREE
i18n 1 row_id 1 foreign_key A 18701 NULL NULL BTREE
i18n 1 field 1 field A 9 NULL NULL BTREE
答案 0 :(得分:1)
如果您的i18n表很大,请尝试将其拆分并使用Multiple Translation Tables。
答案 1 :(得分:1)
尝试将条件从WHERE
转移到ON
连接表。通常,应该没有区别,但如果查询优化器工作错误或无效,那么早期条件会减少行数,从而提高性能。
一些链接:
忘了说,原因,我的意思是你可以
`I18n__slug`.`content` = 'category-slug'
转到ON声明。
类似的东西:
INNER JOIN `fracmerl_dev`.`i18n` AS `I18n__slug`
ON (
`I18n__slug`.`content` = 'category-slug'
AND `Category`.`id` = `I18n__slug`.`foreign_key`
AND `I18n__slugs`.`model` = 'Category'
AND `I18n__slug`.`field` = 'slug'
AND `I18n__slug`.`locale` = 'eng')