2013-07-17 62 views
1

下面的查詢使用CakePHP的i18n表,需要大約1000ms才能運行。我的i18n桌子很大 - 它有大約60萬行。根據Cake模式,我在此表上有默認索引。在CakePHP上查詢大i18n表緩慢

如何加速這樣的查詢?我儘可能緩存它們,但是當需要清除緩存時,這些查詢會運行,並且會顯着降低性能。

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

請提供您的索引 – Dave

+0

感謝戴夫,已經添加了這些的問題。 – Will

回答

1

結果如果你的國際化表很大盡量拆分它,使用Multiple Translation Tables

+0

謝謝 - 儘管我的翻譯表中有90%的行用於相同的模型。無論如何,如果我無法以其他方式加快速度,我可能會嘗試。 – Will

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')