简体   繁体   English

如何优化此 MySQL 查询 - 在视图中? 性能调优

[英]How to optimize this MySQL Query - inside a view? Performance tuning

i have a database with some n:m relation tables and i am using a very big query to combine all those tables.我有一个包含一些 n:m 关系表的数据库,我正在使用一个非常大的查询来组合所有这些表。 Let's take a look firstly at my database:我们先来看看我的数据库:

在此处输入图片说明

I created two Views to compare performance.我创建了两个视图来比较性能。

First View:第一个观点:

CREATE VIEW `band_page1` AS (
SELECT maid, band_name, band_logo, band_img, 
    (SELECT countries.country_name from countries WHERE band_info.id_country = countries.id) as country,
    (SELECT locations.location_name from locations WHERE band_info.id_location = locations.id) as location,
    (SELECT status.status_name from status WHERE band_info.id_status = status.id) as status,
    (SELECT founding.fyear from founding WHERE band_info.id_founding = founding.id) as founding,
    (SELECT active.ayear from active WHERE band_info.id_active = active.id) as active,

    (SELECT GROUP_CONCAT(DISTINCT genres.genre_name ORDER BY genres.genre_name) 
     FROM genres LEFT JOIN band_genres ON band_genres.id_genre = genres.id
     WHERE band_genres.id_band = band_info.maid) AS genre,

    (SELECT GROUP_CONCAT(DISTINCT themes.theme_name ORDER BY themes.theme_name) 
     FROM themes LEFT JOIN band_themes ON band_themes.id_theme = themes.id
     WHERE band_themes.id_band = band_info.maid) AS themes,

    (SELECT GROUP_CONCAT(DISTINCT labels.label_name ORDER BY labels.label_name) 
     FROM labels LEFT JOIN band_labels ON band_labels.id_label = labels.id
     WHERE band_labels.id_band = band_info.maid) AS label

FROM band_info
GROUP BY band_info.maid);

Second View:第二个观点:

CREATE VIEW `band_page2` AS ( 
         SELECT band_info.maid, band_info.band_name, band_info.band_logo, band_info.band_img, 
        (SELECT countries.country_name from countries WHERE band_info.id_country = countries.id) as country, 
        (SELECT locations.location_name from locations WHERE band_info.id_location = locations.id) as location, 
        (SELECT status.status_name from status WHERE band_info.id_status = status.id) as status, 
        (SELECT founding.fyear from founding WHERE band_info.id_founding = founding.id) as founding, 
        (SELECT active.ayear from active WHERE band_info.id_active = active.id) as active, 
        GROUP_CONCAT(DISTINCT genres.genre_name ORDER BY genres.genre_name) AS genre, 
        GROUP_CONCAT(DISTINCT themes.theme_name ORDER BY themes.theme_name) AS themes, 
        GROUP_CONCAT(DISTINCT labels.label_name ORDER BY labels.label_name) AS label 
        FROM band_info 
    LEFT JOIN band_genres ON band_genres.id_band = band_info.maid
    LEFT JOIN band_themes ON band_themes.id_band = band_info.maid
    LEFT JOIN band_labels ON band_labels.id_band = band_info.maid
    LEFT JOIN genres ON genres.id = band_genres.id_genre 
    LEFT JOIN themes ON themes.id = band_themes.id_theme 
    LEFT JOIN labels ON labels.id = band_labels.id_label
    GROUP BY band_info.maid);

When i go to phpmyadmin and open a view it takes 3 seconds on both views to show the query result.当我转到 phpmyadmin 并打开一个视图时,两个视图都需要 3 秒才能显示查询结果。 I am using this view to make a query like the following:我正在使用此视图进行如下查询:

SELECT * FROM band_page1 where maid = '$id';

With php it feels like it is taking ages until i get a result back.使用 php 感觉它需要很长时间才能得到结果。 It is not only taking 3 seconds it takes even much longer.它不仅需要3秒,而且需要更长的时间。 My question is, how can i optimize my queries?我的问题是,如何优化我的查询?

There is such a thing as "over-normalization".有一种叫做“过度规范化”的东西。

There are standard "country codes" that are 2-letters.有两个字母的标准“国家代码”。 Make them CHAR(2) CHARACTER SET ascii , instead of INT to another table.使它们CHAR(2) CHARACTER SET ascii ,而不是INT到另一个表。 That cuts down that column from 4 bytes to 2. And gets rid of a lookup.这将该列从 4 个字节减少到 2 个字节。并摆脱了查找。

YEAR is a 2-byte datatype; YEAR是一个 2 字节的数据类型; don't bother normalizing such.不要打扰正常化这样的。

Consider turning status into a 1-byte ENUM instead of a lookup.考虑将status转换为 1 字节的ENUM而不是查找。

And there may be others.可能还有其他人。

VIEWs are syntactic sugar, and never enhance performance. VIEWs是语法糖,永远不会提高性能。 Sometimes performance is significantly worse.有时性能明显更差。

I don't think there is any use for GROUP BY in the first VIEW .我认为第一个VIEW中的GROUP BY没有任何用处。

band_* tables seem to be many-to-many mapping tables. band_*表似乎是多对多映射表。 Their performance can be improved by following these tips .遵循这些提示可以提高它们的性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM