【问题标题】:Query on large i18n table slow in CakePHP在 CakePHP 中查询大型 i18n 表很慢
【发布时间】:2013-07-17 13:31:40
【问题描述】:

下面的查询使用 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

【问题讨论】:

  • 请提供您的索引
  • 感谢 Dave,已将这些添加到问题中。

标签: mysql cakephp internationalization cakephp-2.3


【解决方案1】:

如果您的 i18n 表很大,请尝试将其拆分并使用 Multiple Translation Tables

【讨论】:

  • 谢谢 - 我的翻译表中 90% 的行都是针对同一模型的。如果我不能以任何其他方式加快速度,我无论如何都可以尝试。
【解决方案2】:

尝试将条件从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')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    相关资源
    最近更新 更多