1

我一直在各种解决方案中使用数据库,但从未真正设计过它们。因此,我对 SQL 的细节还很陌生。我有一个包含许多表的数据库,但有 2 个主要表: Item - 引用许多其他表以获取不会随修订而更改的数据和 Entry - 引用许多其他表以获取不会随修订而更改的数据 每个项目将因此具有1 个或多个修订版(包含所有相关数据)。

我想通过视图选择所有修订(以及项目)的所有数据。我构造了一个查询,如下所示:

CREATE VIEW Single_Query
AS
SELECT  i.REF_CODE AS REF
gp.GROUP_NAME AS Group
v.VERSION_NUMBER AS Version
GROUP_CONCAT(DISTINCT(cy.COUNTRY_DESCRIPTION) SEPARATOR ', ') AS Country
ey.PUB_DATE AS Published
GROUP_CONCAT(DISTINCT(ct.CONTRIBUTOR_NAME) SEPARATOR ', ') AS Author
i.ISBN_CODE AS ISBN
GROUP_CONCAT(DISTINCT CONCAT(cn.COMPONENT_NUMBER, _utf8', ',cn.COMPONENT_DESCRIPTION) SEPARATOR '; ') AS Contents
ey.NOTES AS Notes
i.PRICE AS Price
cl.COLOUR_DESCRIPTION AS Colour
FROM entry AS ey
JOIN item AS i ON ey.ITEM_ID = i.ITEM_ID
JOIN group AS gp ON i.GROUP_ID = gp.GROUP_ID
JOIN version AS v ON ey.VERSION_ID = v.VERSION_ID
JOIN link_country_item AS lci ON i.ITEM_ID = lci.ITEM_ID
JOIN country AS cy ON lci.COUNTRY_ID = cy.COUNTRY_ID
LEFT JOIN link_entry_contributor AS lec ON ey.ENTRY_ID = lec.ENTRY_ID
LEFT JOIN contributor AS ct ON lec.CONTRIBUTOR_ID = ct.CONTRIBUTOR_ID
JOIN contents AS cn ON i.ITEM_ID = cn.ITEM_ID
JOIN colour AS cl ON ey.COLOUR_ID = cl.COLOUR_ID
GROUP BY REF_CODE, VERSION_NUMBER

这需要大约 29 秒才能完成,只有几个条目!但是,如果我运行一个脚本来为项目数据(以及所有引用的数据)和条目数据(以及所有引用的数据)创建临时表,然后从 2 个临时表中选择整个批次,并在 ITEM_ID 上使用单个 JOIN,然后不到半秒即可完成。

请注意,还有许多其他引用的表(为了清楚起见,我省略了它们)。

如果有帮助,项目表会引用组、设置(通过多对多 link_country_item 表)和目录表。

条目表引用版本、贡献者(通过多对多 link_entry_contributor 表)和颜色表。

问题是我真的不想一直使用临时表,因为我不能在视图中使用它们(或者至少我还没有找到如何使用它们)。有没有更优雅的方式在视图中拆分 SQL,以便在这种情况下运行得更快?

提前谢谢了

伊恩

4

1 回答 1

0

我稍微调整了查询​​顺序,并查看您对 REF_CODE 的评论。所以你是对的,原来的索引答案不适合你。但是,如果 item 表位于主要位置,那么 (REF_CODE, ITEM_ID) 上的索引应该有助于提高性能,因为您正在使用表开始,并且为您的 GROUP BY 子句提供相应的索引。

CREATE VIEW Single_Query
AS
SELECT STRAIGHT_JOIN
      i.REF_CODE AS REF
      gp.GROUP_NAME AS Group
      v.VERSION_NUMBER AS Version
      GROUP_CONCAT(DISTINCT(cy.COUNTRY_DESCRIPTION) SEPARATOR ', ') AS Country
      ey.PUB_DATE AS Published
      GROUP_CONCAT(DISTINCT(ct.CONTRIBUTOR_NAME) SEPARATOR ', ') AS Author
      i.ISBN_CODE AS ISBN
      GROUP_CONCAT(DISTINCT CONCAT(cn.COMPONENT_NUMBER, _utf8', ',cn.COMPONENT_DESCRIPTION) SEPARATOR '; ') AS Contents
      ey.NOTES AS Notes
      i.PRICE AS Price
      cl.COLOUR_DESCRIPTION AS Colour
   FROM 
      item AS i 
         JOIN entry ey
            ON i.ITEM_ID = ey.ITEM_ID
            JOIN version AS v  
               ON ey.VERSION_ID = v.VERSION_ID
            JOIN colour AS cl 
               ON ey.COLOUR_ID = cl.COLOUR_ID
            LEFT JOIN link_entry_contributor AS lec 
               ON ey.ENTRY_ID = lec.ENTRY_ID
               LEFT JOIN contributor AS ct 
                  ON lec.CONTRIBUTOR_ID = ct.CONTRIBUTOR_ID
         JOIN group AS gp 
            ON i.GROUP_ID = gp.GROUP_ID
         JOIN link_country_item AS lci 
            ON i.ITEM_ID = lci.ITEM_ID
            JOIN country AS cy 
               ON lci.COUNTRY_ID = cy.COUNTRY_ID
         JOIN contents AS cn 
            ON i.ITEM_ID = cn.ITEM_ID
   GROUP BY 
      REF_CODE, 
      VERSION_NUMBER
于 2013-01-22T18:11:05.867 回答