性能缓慢 MySql 查询、备选方案/建议?

Slow performance MySql query, alternatives / suggestions?

我正在我的硬币网站上实现一个搜索过滤器页面,但现在我有很多条目,速度很慢:

以下是未选择过滤器时的查询:

SELECT
    i.id_items AS id,
    GROUP_CONCAT(DISTINCT iant.translation ORDER BY iant.translation asc SEPARATOR ', ') AS names,
    GROUP_CONCAT(DISTINCT iafv.face_value ORDER BY iafv.face_value ASC SEPARATOR ', ') AS facesValues,
    GROUP_CONCAT(DISTINCT iacut.translation ORDER BY iacut.translation ASC SEPARATOR ', ') AS currencies,
    GROUP_CONCAT(DISTINCT cout.translation ORDER BY cout.translation ASC SEPARATOR ', ') AS countries,
    GROUP_CONCAT(DISTINCT iacot.translation ORDER BY iacot.translation ASC SEPARATOR ', ') AS compositions,
    GROUP_CONCAT(DISTINCT iacc.catalog_code ORDER BY iacc.catalog_code ASC SEPARATOR ', ') AS catalogCodes,
    GROUP_CONCAT(DISTINCT iaio.issues_on ORDER BY iaio.issues_on ASC SEPARATOR ', ') AS issuesOn,
    GROUP_CONCAT(DISTINCT iali.last_issues ORDER BY iali.last_issues ASC SEPARATOR ', ') AS latestIssues,
    MIN(ucfs.price) AS minPrice,
    SUM(ucfs.units) AS totalUnits    
FROM
    items i
INNER JOIN languages AS l 
    ON l.language_code = "en"

LEFT JOIN items_atr_faces_values_match AS iafvm 
    ON iafvm.id_items = i.id_items 
LEFT JOIN items_atr_faces_values AS iafv 
    ON iafv.id_items_atr_faces_values = iafvm.id_items_atr_faces_values


LEFT JOIN items_atr_currencies_match AS iacum 
    ON iacum.id_items = i.id_items 
LEFT JOIN items_atr_currencies_translations AS iacut 
    ON iacut.id_items_atr_currencies = iacum.id_items_atr_currencies
    AND iacut.id_language_code = l.id_languages 
LEFT JOIN items_atr_currencies AS iacu 
    ON iacu.id_items_atr_currencies = iacum.id_items_atr_currencies 


LEFT JOIN items_atr_countries_match AS iacoum 
    ON iacoum.id_items = i.id_items 
LEFT JOIN items_atr_countries_translations AS cout 
    ON cout.id_items_atr_countries = iacoum.id_items_atr_countries
    AND cout.id_language_code = l.id_languages 
LEFT JOIN items_atr_countries AS cou 
    ON cou.id_items_atr_countries = iacoum.id_items_atr_countries 


LEFT JOIN items_atr_compositions_match AS iacom 
    ON iacom.id_items = i.id_items 
LEFT JOIN items_atr_compositions_translations AS iacot 
    ON iacot.id_items_atr_compositions = iacom.id_items_atr_compositions 
    AND iacot.id_language_code = l.id_languages 
LEFT JOIN items_atr_compositions AS iaco 
    ON iaco.id_items_atr_compositions = iacom.id_items_atr_compositions 


LEFT JOIN items_atr_catalog_codes_match AS iaccm 
    ON iaccm.id_items = i.id_items
LEFT JOIN items_atr_catalog_codes AS iacc 
    ON iacc.id_items_atr_catalog_codes = iaccm.id_items_atr_catalog_codes


LEFT JOIN items_atr_issues_on_match AS iaiom 
    ON iaiom.id_items = i.id_items
LEFT JOIN items_atr_issues_on AS iaio 
    ON iaio.id_items_atr_issues_on = iaiom.id_items_atr_issues_on

LEFT JOIN items_atr_last_issues_match AS ialim 
    ON ialim.id_items = i.id_items
LEFT JOIN items_atr_last_issues AS iali 
    ON iali.id_items_atr_last_issues = ialim.id_items_atr_last_issues


LEFT JOIN items_atr_names_match AS ianm 
    ON ianm.id_items = i.id_items
LEFT JOIN items_atr_names_translations AS iant 
    ON iant.id_items_atr_names = ianm.id_items_atr_names 
    AND iant.id_language_code = l.id_languages 
LEFT JOIN items_atr_names AS ian 
    ON ian.id_items_atr_names = ianm.id_items_atr_names          


LEFT JOIN users AS u On u.status = 'active' 
LEFT JOIN users_coins_for_sale AS ucfs 
    ON ucfs.id_users = u.id_users AND ucfs.id_items = i.id_items  



GROUP BY id

ORDER BY 2 asc

LIMIT 0, 20

解释如下:

我正在使用 Group Concat,因为每个项目都可以有一个或多个与属性(名称、面值等)匹配的项。

查询 运行 需要 1.3 秒,包含 15k 个条目。这些表最终将有 100k 个条目,因此 运行 查询的时间也会增加...

起初我认为 Group_Concat 是导致查询速度变慢的原因,但是在删除 LIMIT 0, 20 之后我发现 运行.[=18 需要相同的时间=]

我尝试将 Limit 放入子查询中:

...
FROM
    (SELECT id_items FROM items LIMIT 0, 20) AS i
INNER JOIN languages AS l 
...

现在查询速度很快,但结果不是我所期望的。

你们有什么解决这个问题的建议吗?

另外,我在这个查询中遇到了类似的问题,要计算项目的数量:

SELECT
    COUNT(DISTINCT i.id_items) AS number  
FROM
    items i
INNER JOIN languages AS l 
    ON l.language_code = "en"

LEFT JOIN items_atr_faces_values_match AS iafvm 
    ON iafvm.id_items = i.id_items 
LEFT JOIN items_atr_faces_values AS iafv 
    ON iafv.id_items_atr_faces_values = iafvm.id_items_atr_faces_values


LEFT JOIN items_atr_currencies_match AS iacum 
    ON iacum.id_items = i.id_items 
LEFT JOIN items_atr_currencies_translations AS iacut 
    ON iacut.id_items_atr_currencies = iacum.id_items_atr_currencies
    AND iacut.id_language_code = l.id_languages 
LEFT JOIN items_atr_currencies AS iacu 
    ON iacu.id_items_atr_currencies = iacum.id_items_atr_currencies 


LEFT JOIN items_atr_countries_match AS iacoum 
    ON iacoum.id_items = i.id_items 
LEFT JOIN items_atr_countries_translations AS cout 
    ON cout.id_items_atr_countries = iacoum.id_items_atr_countries
    AND cout.id_language_code = l.id_languages 
LEFT JOIN items_atr_countries AS cou 
    ON cou.id_items_atr_countries = iacoum.id_items_atr_countries 


LEFT JOIN items_atr_compositions_match AS iacom 
    ON iacom.id_items = i.id_items 
LEFT JOIN items_atr_compositions_translations AS iacot 
    ON iacot.id_items_atr_compositions = iacom.id_items_atr_compositions 
    AND iacot.id_language_code = l.id_languages 
LEFT JOIN items_atr_compositions AS iaco 
    ON iaco.id_items_atr_compositions = iacom.id_items_atr_compositions 


LEFT JOIN items_atr_catalog_codes_match AS iaccm 
    ON iaccm.id_items = i.id_items
LEFT JOIN items_atr_catalog_codes AS iacc 
    ON iacc.id_items_atr_catalog_codes = iaccm.id_items_atr_catalog_codes


LEFT JOIN items_atr_issues_on_match AS iaiom 
    ON iaiom.id_items = i.id_items
LEFT JOIN items_atr_issues_on AS iaio 
    ON iaio.id_items_atr_issues_on = iaiom.id_items_atr_issues_on

LEFT JOIN items_atr_last_issues_match AS ialim 
    ON ialim.id_items = i.id_items
LEFT JOIN items_atr_last_issues AS iali 
    ON iali.id_items_atr_last_issues = ialim.id_items_atr_last_issues


LEFT JOIN items_atr_names_match AS ianm 
    ON ianm.id_items = i.id_items
LEFT JOIN items_atr_names_translations AS iant 
    ON iant.id_items_atr_names = ianm.id_items_atr_names 
    AND iant.id_language_code = l.id_languages 
LEFT JOIN items_atr_names AS ian 
    ON ian.id_items_atr_names = ianm.id_items_atr_names          


LEFT JOIN users AS u On u.status = 'active' 
LEFT JOIN users_coins_for_sale AS ucfs 
    ON ucfs.id_users = u.id_users AND ucfs.id_items = i.id_items  

LIMIT 1

这需要 0.8 秒。

解释:

我 运行 我的搜索页面中的两个查询(需要第二个用于分页),所以最终加载需要 2 秒。现在有 15,000 个项目,所以当我有 100,000 个项目时,它会花费更长的时间。

如有任何建议,我们将不胜感激。

提前致谢

更新:这里是创建数据:

CREATE TABLE IF NOT EXISTS `items` (
    `id_items` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_users` int(11) unsigned NOT NULL DEFAULT '0',
    `date` date NOT NULL,
    `views` bigint(20) NOT NULL DEFAULT '0',
    `status` enum('draft','published') NOT NULL DEFAULT 'draft',
    PRIMARY KEY (`id_items`),
    UNIQUE KEY `id_items` (`id_items`),
    KEY `id_users` (`id_users`),
    CONSTRAINT `FK_items_users` FOREIGN KEY (`id_users`) REFERENCES `users` (`id_users`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Lista de items';

CREATE TABLE IF NOT EXISTS `items_atr_catalog_codes` (
    `id_items_atr_catalog_codes` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `catalog_code` varchar(100) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_catalog_codes`),
    UNIQUE KEY `id_items_atr_catalog_codes` (`id_items_atr_catalog_codes`),
    FULLTEXT KEY `catalog_code` (`catalog_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Los diferentes códigos de catálogo que tienen las monedas';


CREATE TABLE IF NOT EXISTS `items_atr_catalog_codes_match` (
    `id_items_atr_catalog_codes_match` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_catalog_codes` int(11) unsigned NOT NULL,
    `id_items` int(11) unsigned NOT NULL,
    PRIMARY KEY (`id_items_atr_catalog_codes_match`),
    UNIQUE KEY `id_items_atr_catalog_codes_match` (`id_items_atr_catalog_codes_match`),
    KEY `id_items` (`id_items`),
    KEY `id_items_atr_catalog_codes` (`id_items_atr_catalog_codes`),
    CONSTRAINT `FK_catalog_codes_items_match_catalog_codes` FOREIGN KEY (`id_items_atr_catalog_codes`) REFERENCES `items_atr_catalog_codes` (`id_items_atr_catalog_codes`),
    CONSTRAINT `FK_catalog_codes_items_match_items` FOREIGN KEY (`id_items`) REFERENCES `items` (`id_items`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Asociación de monedas con los códigos del catálogo';


CREATE TABLE IF NOT EXISTS `items_atr_compositions` (
    `id_items_atr_compositions` int(11) unsigned NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id_items_atr_compositions`),
    UNIQUE KEY `id_items_atr_compositions` (`id_items_atr_compositions`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Lista de las diferentes composiciones';


CREATE TABLE IF NOT EXISTS `items_atr_compositions_match` (
    `id_items_atr_compositions_match` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_compositions` int(11) unsigned NOT NULL DEFAULT '0',
    `id_items` int(11) unsigned NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_compositions_match`),
    UNIQUE KEY `id_items_atr_compositions_match` (`id_items_atr_compositions_match`),
    KEY `id_items` (`id_items`),
    KEY `id_items_atr_compositions` (`id_items_atr_compositions`),
    CONSTRAINT `FK_compositions_items_match_compositions` FOREIGN KEY (`id_items_atr_compositions`) REFERENCES `items_atr_compositions` (`id_items_atr_compositions`),
    CONSTRAINT `FK_compositions_items_match_items` FOREIGN KEY (`id_items`) REFERENCES `items` (`id_items`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Las diferentes composiciones que puede tener un item';


CREATE TABLE IF NOT EXISTS `items_atr_compositions_translations` (
    `id_items_atr_compositions_translations` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_compositions` int(11) unsigned NOT NULL DEFAULT '0',
    `id_language_code` int(11) unsigned NOT NULL DEFAULT '0',
    `translation` varchar(250) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_compositions_translations`),
    UNIQUE KEY `id_items_atr_compositions_translations` (`id_items_atr_compositions_translations`),
    KEY `id_language_code` (`id_language_code`),
    KEY `id_items_atr_compositions` (`id_items_atr_compositions`),
    FULLTEXT KEY `translation` (`translation`),
    CONSTRAINT `FK_compositions_translations_compositions` FOREIGN KEY (`id_items_atr_compositions`) REFERENCES `items_atr_compositions` (`id_items_atr_compositions`),
    CONSTRAINT `FK_compositions_translations_languages` FOREIGN KEY (`id_language_code`) REFERENCES `languages` (`id_languages`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Traducciones de las composiciones';

CREATE TABLE IF NOT EXISTS `items_atr_countries` (
    `id_items_atr_countries` int(11) unsigned NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id_items_atr_countries`),
    UNIQUE KEY `id_items_atr_countries` (`id_items_atr_countries`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE IF NOT EXISTS `items_atr_countries_match` (
    `id_items_atr_countries_match` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_countries` int(11) unsigned NOT NULL,
    `id_items` int(11) unsigned NOT NULL,
    PRIMARY KEY (`id_items_atr_countries_match`),
    UNIQUE KEY `items_atr_countries_match` (`id_items_atr_countries_match`),
    KEY `id_items` (`id_items`),
    KEY `id_items_atr_countries` (`id_items_atr_countries`),
    CONSTRAINT `FK__countries` FOREIGN KEY (`id_items_atr_countries`) REFERENCES `items_atr_countries` (`id_items_atr_countries`),
    CONSTRAINT `FK__items` FOREIGN KEY (`id_items`) REFERENCES `items` (`id_items`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='A que pais pertenece cada item';


CREATE TABLE IF NOT EXISTS `items_atr_countries_translations` (
    `id_items_atr_countries_translations` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_countries` int(11) unsigned NOT NULL DEFAULT '0',
    `id_language_code` int(11) unsigned NOT NULL DEFAULT '0',
    `translation` varchar(250) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_countries_translations`),
    UNIQUE KEY `id_items_atr_countries_translations` (`id_items_atr_countries_translations`),
    KEY `id_items_atr_countries` (`id_items_atr_countries`),
    KEY `id_language_code` (`id_language_code`),
    FULLTEXT KEY `translation` (`translation`),
    CONSTRAINT `FK__items_atr_countries` FOREIGN KEY (`id_items_atr_countries`) REFERENCES `items_atr_countries` (`id_items_atr_countries`),
    CONSTRAINT `FK_items_atr_countries_translations_languages` FOREIGN KEY (`id_language_code`) REFERENCES `languages` (`id_languages`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE IF NOT EXISTS `items_atr_currencies` (
    `id_items_atr_currencies` int(11) unsigned NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id_items_atr_currencies`),
    UNIQUE KEY `id_items_atr_currencies` (`id_items_atr_currencies`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Diferentes divisas de las monedas';


CREATE TABLE IF NOT EXISTS `items_atr_currencies_match` (
    `id_items_atr_currencies_match` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_currencies` int(11) unsigned NOT NULL DEFAULT '0',
    `id_items` int(11) unsigned NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_currencies_match`),
    UNIQUE KEY `id_items_atr_currencies_match` (`id_items_atr_currencies_match`),
    KEY `id_items_atr_currencies` (`id_items_atr_currencies`),
    KEY `id_items` (`id_items`),
    CONSTRAINT `FK_items_atr_currencies_match_items` FOREIGN KEY (`id_items`) REFERENCES `items` (`id_items`),
    CONSTRAINT `FK_items_atr_currencies_match_items_atr_currencies` FOREIGN KEY (`id_items_atr_currencies`) REFERENCES `items_atr_currencies` (`id_items_atr_currencies`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Asociación de las monedas con su divisa';


CREATE TABLE IF NOT EXISTS `items_atr_currencies_translations` (
    `id_items_atr_currencies_translations` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_currencies` int(11) unsigned NOT NULL DEFAULT '0',
    `id_language_code` int(11) unsigned NOT NULL DEFAULT '0',
    `translation` varchar(255) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_currencies_translations`),
    UNIQUE KEY `id_items_atr_currencies_translations` (`id_items_atr_currencies_translations`),
    KEY `id_items_atr_currencies` (`id_items_atr_currencies`),
    KEY `id_language_code` (`id_language_code`),
    FULLTEXT KEY `translation` (`translation`),
    CONSTRAINT `FK_items_atr_currencies_translations_items_atr_currencies` FOREIGN KEY (`id_items_atr_currencies`) REFERENCES `items_atr_currencies` (`id_items_atr_currencies`),
    CONSTRAINT `FK_items_atr_currencies_translations_languages` FOREIGN KEY (`id_language_code`) REFERENCES `languages` (`id_languages`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Traducciones de las divisas';


CREATE TABLE IF NOT EXISTS `items_atr_faces_values` (
    `id_items_atr_faces_values` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `face_value` decimal(8,2) unsigned NOT NULL DEFAULT '0.00',
    PRIMARY KEY (`id_items_atr_faces_values`),
    UNIQUE KEY `id_items_atr_faces_values` (`id_items_atr_faces_values`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Valores faciales de las monedas';


CREATE TABLE IF NOT EXISTS `items_atr_faces_values_match` (
    `id_items_atr_faces_values_match` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_faces_values` int(11) unsigned NOT NULL DEFAULT '0',
    `id_items` int(11) unsigned NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_faces_values_match`),
    UNIQUE KEY `id_items_atr_faces_values_match` (`id_items_atr_faces_values_match`),
    KEY `id_items_atr_faces_values` (`id_items_atr_faces_values`),
    KEY `id_items` (`id_items`),
    CONSTRAINT `FK_items_atr_faces_values_match_items` FOREIGN KEY (`id_items`) REFERENCES `items` (`id_items`),
    CONSTRAINT `FK_items_atr_faces_values_match_items_atr_faces_values` FOREIGN KEY (`id_items_atr_faces_values`) REFERENCES `items_atr_faces_values` (`id_items_atr_faces_values`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Asociación de las monedas con sus valores faciales';


CREATE TABLE IF NOT EXISTS `items_atr_issues_on` (
    `id_items_atr_issues_on` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `issues_on` varchar(6) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_issues_on`),
    UNIQUE KEY `id_items_atr_issues_on` (`id_items_atr_issues_on`),
    FULLTEXT KEY `issues_on` (`issues_on`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Fecha en la que se emitió por primera vez la moneda';


CREATE TABLE IF NOT EXISTS `items_atr_issues_on_match` (
    `id_items_atr_issues_on_match` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_issues_on` int(11) unsigned NOT NULL,
    `id_items` int(11) unsigned NOT NULL,
    PRIMARY KEY (`id_items_atr_issues_on_match`),
    UNIQUE KEY `id_items_atr_issues_on_match` (`id_items_atr_issues_on_match`),
    KEY `id_items_atr_issues_on` (`id_items_atr_issues_on`),
    KEY `id_items` (`id_items`),
    CONSTRAINT `FK_items_atr_issues_on_match_items` FOREIGN KEY (`id_items`) REFERENCES `items` (`id_items`),
    CONSTRAINT `FK_items_atr_issues_on_match_items_atr_issues_on` FOREIGN KEY (`id_items_atr_issues_on`) REFERENCES `items_atr_issues_on` (`id_items_atr_issues_on`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Asociaciones de emisiones con las monedas';


CREATE TABLE IF NOT EXISTS `items_atr_last_issues` (
    `id_items_atr_last_issues` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `last_issues` varchar(6) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_last_issues`),
    UNIQUE KEY `id_items_atr_last_issues` (`id_items_atr_last_issues`),
    FULLTEXT KEY `last_issues` (`last_issues`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Atributo de última emisión de la moneda';


CREATE TABLE IF NOT EXISTS `items_atr_last_issues_match` (
    `id_items_atr_last_issues_match` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_last_issues` int(11) unsigned NOT NULL DEFAULT '0',
    `id_items` int(11) unsigned NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_last_issues_match`),
    UNIQUE KEY `id_items_atr_last_issues_match` (`id_items_atr_last_issues_match`),
    KEY `id_items_atr_last_issues` (`id_items_atr_last_issues`),
    KEY `id_items` (`id_items`),
    CONSTRAINT `FK_items_atr_last_issues_match_items` FOREIGN KEY (`id_items`) REFERENCES `items` (`id_items`),
    CONSTRAINT `FK_items_atr_last_issues_match_items_atr_last_issues` FOREIGN KEY (`id_items_atr_last_issues`) REFERENCES `items_atr_last_issues` (`id_items_atr_last_issues`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Asociaciones entre las últimas emisiones y las monedas';


CREATE TABLE IF NOT EXISTS `items_atr_names` (
    `id_items_atr_names` int(11) unsigned NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id_items_atr_names`),
    UNIQUE KEY `id_items_atr_names` (`id_items_atr_names`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Contiene el atributo nombre de los items';


CREATE TABLE IF NOT EXISTS `items_atr_names_match` (
    `id_items_atr_names_match` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_names` int(11) unsigned NOT NULL DEFAULT '0',
    `id_items` int(11) unsigned NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_names_match`),
    UNIQUE KEY `id_items_atr_names_match` (`id_items_atr_names_match`),
    KEY `id_items_atr_names` (`id_items_atr_names`),
    KEY `id_items` (`id_items`),
    CONSTRAINT `FK_items_atr_names_match_items` FOREIGN KEY (`id_items`) REFERENCES `items` (`id_items`),
    CONSTRAINT `FK_items_atr_names_match_items_atr_names` FOREIGN KEY (`id_items_atr_names`) REFERENCES `items_atr_names` (`id_items_atr_names`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Asociación del atributo nombre con las monedas';


CREATE TABLE IF NOT EXISTS `items_atr_names_translations` (
    `id_items_atr_names_translations` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items_atr_names` int(11) unsigned NOT NULL DEFAULT '0',
    `id_language_code` int(11) unsigned NOT NULL DEFAULT '0',
    `translation` varchar(250) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id_items_atr_names_translations`),
    UNIQUE KEY `id_items_atr_names_translations` (`id_items_atr_names_translations`),
    KEY `id_language_code` (`id_language_code`),
    KEY `id_items_atr_names` (`id_items_atr_names`),
    KEY `STR_LEVE_idx` (`translation`),
    FULLTEXT KEY `translation` (`translation`),
    CONSTRAINT `FK_items_atr_names_translations_items_atr_names` FOREIGN KEY (`id_items_atr_names`) REFERENCES `items_atr_names` (`id_items_atr_names`),
    CONSTRAINT `FK_items_atr_names_translations_languages` FOREIGN KEY (`id_language_code`) REFERENCES `languages` (`id_languages`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Traducciones del atributo nombre';


CREATE TABLE IF NOT EXISTS `users` (
    `id_users` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_languages` int(11) unsigned NOT NULL,
    `password` char(128) NOT NULL,
    `user_name` char(128) NOT NULL,
    `last_login` datetime DEFAULT NULL,
    `ip_register` varbinary(16) DEFAULT NULL,
    `ip_last_login` varbinary(16) DEFAULT NULL,
    `creation_date` datetime DEFAULT NULL,
    `email` varchar(254) DEFAULT NULL,
    `fb_user_id` varchar(255) DEFAULT NULL,
    `fb_access_token` varchar(255) DEFAULT NULL,
    `regen_password` varchar(254) DEFAULT NULL,
    `activation_token` varchar(254) DEFAULT NULL,
    `affiliated` varchar(30) NOT NULL DEFAULT 'no',
    `credit` decimal(10,2) NOT NULL DEFAULT '0.00',
    `status` enum('inactive','active','vacation','deleted') NOT NULL DEFAULT 'inactive',
    `news` tinyint(1) NOT NULL DEFAULT '1',
    `promotions` tinyint(1) NOT NULL DEFAULT '1',
    PRIMARY KEY (`id_users`),
    UNIQUE KEY `email` (`email`),
    KEY `id_languages` (`id_languages`),
    FULLTEXT KEY `fb_user_id` (`fb_user_id`),
    FULLTEXT KEY `email2` (`email`),
    FULLTEXT KEY `user_name` (`user_name`),
    CONSTRAINT `FK_users_languages` FOREIGN KEY (`id_languages`) REFERENCES `languages` (`id_languages`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Lista de usuarios en la web';


CREATE TABLE IF NOT EXISTS `users_coins_for_sale` (
    `id_users_coins_for_sale` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `id_items` int(11) unsigned NOT NULL,
    `id_users` int(11) unsigned NOT NULL,
    `units` int(5) unsigned NOT NULL,
    `year` varchar(5) NOT NULL,
    `grade` enum('good','very_good','fine','very_fine','extra_fine','about_uncirculated','uncirculated','brilliant_uncirculated','proof') NOT NULL,
    `price` decimal(8,2) unsigned NOT NULL,
    `picture` varchar(500) DEFAULT NULL,
    `comment` varchar(500) DEFAULT NULL,
    `date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id_users_coins_for_sale`),
    UNIQUE KEY `id_users_coins_for_sale_unique` (`id_users_coins_for_sale`),
    KEY `id_items` (`id_items`),
    KEY `id_users` (`id_users`),
    KEY `year` (`year`),
    KEY `grade` (`grade`),
    KEY `id_users_coins_for_sale` (`id_users_coins_for_sale`),
    CONSTRAINT `FK_users_coins_for_sale_items` FOREIGN KEY (`id_items`) REFERENCES `items` (`id_items`),
    CONSTRAINT `FK_users_coins_for_sale_users` FOREIGN KEY (`id_users`) REFERENCES `users` (`id_users`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

您的查询非常复杂,因为要执行所有笛卡尔积。有点难理解,因为你没有提供数据模型。

提高性能的关键是在加入之前进行聚合,这样你就不会得到笛卡尔积。有两种方法可以做到这一点。一种是在 FROM 子句中预先聚合表。另一种是使用相关子查询。当您进一步过滤行时(比如获得 20 行),相关子查询通常是更好的选择。

您可以通过使用子查询在连接之前进行聚合来简化它。以聚合为例:

SELECT i.id_items AS id,
       (SELECT GROUP_CONCAT(iafv.face_value SEPARATOR ', ')
        FROM tems_atr_faces_values_match iafvm JOIN
             items_atr_faces_values iafv 
             ON  iafv.id_items_atr_faces_values = iafvm.id_items_atr_faces_values AND
                 iafvm.id_items = i.id_items 
       ) as facesValues
       . . .
FROM items i INNER JOIN
     languages AS l 
     ON l.language_code = 'en';

对于此查询,您需要 items_atr_faces_values_match(id_items, id_items_atr_faces_values)items_atr_faces_values(id_items_atr_faces_values, face_value.

上的索引

你需要为你所有的关系重复这个。

我找到了解决方案,在 0.125 / 0.180 秒内得到了结果

诀窍是首先使用您要排序的属性和选定的分页执行子查询,然后在其余的连接中使用项目 ID。

例如,选择名称作为排序依据的属性:

SELECT
    i.id_items AS id,
    GROUP_CONCAT(DISTINCT iant.translation ORDER BY iant.translation asc SEPARATOR ', ') AS names,
    GROUP_CONCAT(DISTINCT iafv.face_value ORDER BY iafv.face_value ASC SEPARATOR ', ') AS facesValues,
    GROUP_CONCAT(DISTINCT iacut.translation ORDER BY iacut.translation ASC SEPARATOR ', ') AS currencies,
    GROUP_CONCAT(DISTINCT cout.translation ORDER BY cout.translation ASC SEPARATOR ', ') AS countries,
    GROUP_CONCAT(DISTINCT iacot.translation ORDER BY iacot.translation ASC SEPARATOR ', ') AS compositions,
    GROUP_CONCAT(DISTINCT iacc.catalog_code ORDER BY iacc.catalog_code ASC SEPARATOR ', ') AS catalogCodes,
    GROUP_CONCAT(DISTINCT iaio.issues_on ORDER BY iaio.issues_on ASC SEPARATOR ', ') AS issuesOn,
    GROUP_CONCAT(DISTINCT iali.last_issues ORDER BY iali.last_issues ASC SEPARATOR ', ') AS latestIssues,
    MIN(ucfs.price) AS minPrice,
    SUM(ucfs.units) AS totalUnits
FROM
    (SELECT
        i.id_items,
        GROUP_CONCAT(DISTINCT iant.translation ORDER BY iant.translation asc SEPARATOR ', ') AS names
    FROM
        items i
    INNER JOIN languages AS l ON l.language_code = "en"

    LEFT JOIN items_atr_names_match AS ianm ON ianm.id_items = i.id_items
    LEFT JOIN items_atr_names_translations AS iant ON iant.id_items_atr_names = ianm.id_items_atr_names 
        AND iant.id_language_code = l.id_languages 
    LEFT JOIN items_atr_names AS ian ON ian.id_items_atr_names = ianm.id_items_atr_names          

    GROUP BY id_items

    ORDER BY 2 asc

    LIMIT 0, 20) AS i
INNER JOIN languages AS l ON l.language_code = "en"

LEFT JOIN items_atr_faces_values_match AS iafvm ON iafvm.id_items = i.id_items 
LEFT JOIN items_atr_faces_values AS iafv ON iafv.id_items_atr_faces_values = iafvm.id_items_atr_faces_values

LEFT JOIN items_atr_currencies_match AS iacum ON iacum.id_items = i.id_items 
LEFT JOIN items_atr_currencies_translations AS iacut ON iacut.id_items_atr_currencies = iacum.id_items_atr_currencies AND iacut.id_language_code = l.id_languages 
LEFT JOIN items_atr_currencies AS iacu ON iacu.id_items_atr_currencies = iacum.id_items_atr_currencies 


LEFT JOIN items_atr_countries_match AS iacoum ON iacoum.id_items = i.id_items 
LEFT JOIN items_atr_countries_translations AS cout ON cout.id_items_atr_countries = iacoum.id_items_atr_countries AND cout.id_language_code = l.id_languages 
LEFT JOIN items_atr_countries AS cou ON cou.id_items_atr_countries = iacoum.id_items_atr_countries 



LEFT JOIN items_atr_compositions_match AS iacom ON iacom.id_items = i.id_items 
LEFT JOIN items_atr_compositions_translations AS iacot ON iacot.id_items_atr_compositions = iacom.id_items_atr_compositions AND iacot.id_language_code = l.id_languages 
LEFT JOIN items_atr_compositions AS iaco ON iaco.id_items_atr_compositions = iacom.id_items_atr_compositions 



LEFT JOIN items_atr_catalog_codes_match AS iaccm ON iaccm.id_items = i.id_items
LEFT JOIN items_atr_catalog_codes AS iacc ON iacc.id_items_atr_catalog_codes = iaccm.id_items_atr_catalog_codes


LEFT JOIN items_atr_issues_on_match AS iaiom ON iaiom.id_items = i.id_items
LEFT JOIN items_atr_issues_on AS iaio ON iaio.id_items_atr_issues_on = iaiom.id_items_atr_issues_on


LEFT JOIN items_atr_last_issues_match AS ialim ON ialim.id_items = i.id_items
LEFT JOIN items_atr_last_issues AS iali ON iali.id_items_atr_last_issues = ialim.id_items_atr_last_issues


LEFT JOIN items_atr_names_match AS ianm ON ianm.id_items = i.id_items
LEFT JOIN items_atr_names_translations AS iant ON iant.id_items_atr_names = ianm.id_items_atr_names AND iant.id_language_code = l.id_languages 
LEFT JOIN items_atr_names AS ian ON ian.id_items_atr_names = ianm.id_items_atr_names          

LEFT JOIN users AS u On u.status = 'active' 
LEFT JOIN users_coins_for_sale AS ucfs ON ucfs.id_users = u.id_users AND ucfs.id_items = i.id_items  


GROUP BY id

ORDER BY 2 asc

我希望这个回答能为其他人节省时间。

和平

太多table。

不要 "normalize" 简单的东西,例如 face_value 和 issues_on(可能还有其他东西。它会导致额外的 JOINs 而没有额外的灵活性等

我看到国家 ID,但没有国家名称??使用 代替 table 和 id:

可能会更好
country_code CHAR(2) CHARACTER SET ascii

并使用标准的 2 字母国家/地区代码。 (它还会在各种 table 中用 2 字节字符串替换 4 字节 INT

此外,由于 PRIMARY KEY 根据定义(在 MySQL 中),UNIQUE:

PRIMARY KEY(x)
UNIQUE     (x)  -- DROP this

你需要LEFT吗?也就是说,'right' table 中的行可能丢失了吗?如果不是,请删除 LEFT.

清理完这些后,要求再次审核。