У нас есть 2 таблицы, которые предоставляют список школ.
Первая таблица (school_data
) - это исходные данные из общедоступной базы данных, которая обновляется при публикации правительством новых данных.
Вторая таблица school_data_overwrites
имеет большинство тех же полей и используется для исправления опечаток и неточностей в первой таблице (она находится в отдельной таблице, чтобы иметь возможность обновлять данные, сохраняя наши правки).
Затем мы используем представление, которое должен запрашивать наш код, который для каждой строки должен показывать значение от school_data_overwrites
, если оно присутствует, или откат до school_data
, если его нет. Что является сложным, так это то, что некоторые строки имеют parent_school_id
, который ссылается на другую строку, которая сама может иметь перезаписанные данные.
Мы получили следующее представление, но оно очень медленное и использует много ресурсов ЦП:
SELECT
school_data.id AS id,
school_data.ref_id AS ref_id,
school_data.schoolyear AS schoolyear,
IF(school_data_overwrites.type <> '' OR school_data_overwrites.type <> NULL, school_data_overwrites.type, school_data.type) AS type,
IF(school_data_overwrites.name <> '' OR school_data_overwrites.name <> NULL, school_data_overwrites.name, school_data.name) AS name,
IF(school_data_overwrites.email <> '' OR school_data_overwrites.email <> NULL, school_data_overwrites.email, school_data.email) AS email,
IF(school_data_overwrites.certified_email <> '' OR school_data_overwrites.certified_email <> NULL, school_data_overwrites.certified_email, school_data.certified_email) AS certified_email,
IF(school_data_overwrites.website <> '' OR school_data_overwrites.website <> NULL, school_data_overwrites.website, school_data.website) AS website,
IF(school_data_overwrites.address <> '' OR school_data_overwrites.address <> NULL, school_data_overwrites.address, school_data.address) AS address,
IF(school_data_overwrites.postcode <> '' OR school_data_overwrites.postcode <> NULL, school_data_overwrites.postcode, school_data.postcode) AS postcode,
school_data.city_id AS city_id,
school_data.city_name AS city_name,
school_data.province_id AS province_id,
school_data.province_name AS province_name,
school_data.province_iso_code AS province_iso_code,
school_data.region_id AS region_id,
school_data.region_name AS region_name,
school_data.nuts3_2010_code AS nuts3_2010_code,
school_data_overwrites.facebook_url AS facebook_url,
school_data_overwrites.twitter_url AS twitter_url,
school_data_overwrites.vip AS vip,
school_data.parent_school_id AS parent_school_id,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.city_id, '') parent_school_ref_id,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.city_id, '') parent_school_schoolyear,
IF(
school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL,
IF(parent_school_data_overwrites.type <> '' OR parent_school_data_overwrites.type <> NULL, parent_school_data_overwrites.type, parent_school_data.type),
''
) AS parent_school_type,
IF(
school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL,
IF(parent_school_data_overwrites.name <> '' OR parent_school_data_overwrites.name <> NULL, parent_school_data_overwrites.name, parent_school_data.name),
''
) AS parent_school_name,
IF(
school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL,
IF(parent_school_data_overwrites.email <> '' OR parent_school_data_overwrites.email <> NULL, parent_school_data_overwrites.email, parent_school_data.email),
''
) AS parent_school_email,
IF(
school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL,
IF(parent_school_data_overwrites.certified_email <> '' OR parent_school_data_overwrites.certified_email <> NULL, parent_school_data_overwrites.certified_email, parent_school_data.certified_email),
''
) AS parent_school_certified_email,
IF(
school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL,
IF(parent_school_data_overwrites.website <> '' OR parent_school_data_overwrites.website <> NULL, parent_school_data_overwrites.website, parent_school_data.website),
''
) AS parent_school_website,
IF(
school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL,
IF(parent_school_data_overwrites.address <> '' OR parent_school_data_overwrites.address <> NULL, parent_school_data_overwrites.address, parent_school_data.address),
''
) AS parent_school_address,
IF(
school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL,
IF(parent_school_data_overwrites.postcode <> '' OR parent_school_data_overwrites.postcode <> NULL, parent_school_data_overwrites.postcode, parent_school_data.postcode),
''
) AS parent_school_postcode,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.city_id, '') AS parent_school_city_id,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.city_name, '') AS parent_school_city_name,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.province_id, '') AS parent_school_province_id,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.province_name, '') AS parent_school_province_name,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.province_iso_code, '') AS parent_school_province_iso_code,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.region_id, '') AS parent_school_region_id,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.region_name, '') AS parent_school_region_name,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data.nuts3_2010_code, '') AS parent_school_nuts3_2010_code,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data_overwrites.facebook_url, '') AS parent_school_facebook_url,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data_overwrites.twitter_url, '') AS parent_school_twitter_url,
IF(school_data.parent_school_id <> '' OR school_data.parent_school_id <> NULL, parent_school_data_overwrites.vip, '') AS parent_school_vip
FROM
school_data LEFT JOIN school_data_overwrites ON school_data_overwrites.school_id = school_data.id,
school_data parent_school_data LEFT JOIN school_data_overwrites parent_school_data_overwrites ON parent_school_data_overwrites.school_id = parent_school_data.parent_school_id
WHERE parent_school_data.id = school_data.id;
school_data
выглядит так:
+---------------------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------------+--------------+------+-----+---------+-------+
| id | varchar(255) | YES | | NULL | |
| ref_id | varchar(255) | YES | | NULL | |
| schoolyear | int(11) | YES | MUL | NULL | |
| type | varchar(255) | YES | MUL | NULL | |
| name | varchar(255) | YES | MUL | NULL | |
| email | varchar(255) | YES | MUL | NULL | |
| certified_email | varchar(255) | YES | MUL | NULL | |
| website | varchar(255) | YES | | NULL | |
| address | varchar(255) | YES | MUL | NULL | |
| cad_code | varchar(255) | YES | MUL | NULL | |
| postcode | varchar(255) | YES | MUL | NULL | |
| city_name | varchar(255) | YES | MUL | NULL | |
| city_id | varchar(255) | YES | MUL | NULL | |
| province_name | varchar(255) | YES | MUL | NULL | |
| province_id | varchar(255) | YES | MUL | NULL | |
| province_iso_code | varchar(255) | YES | MUL | NULL | |
| region_name | varchar(255) | YES | MUL | NULL | |
| region_id | varchar(255) | YES | MUL | NULL | |
| nuts3_2010_code | varchar(255) | YES | MUL | NULL | |
| parent_school_id | varchar(255) | YES | MUL | NULL | |
Это school_data_overwrites
:
+---------------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| school_id | varchar(255) | NO | UNI | NULL | |
| type | varchar(255) | YES | MUL | NULL | |
| name | varchar(255) | YES | MUL | NULL | |
| email | varchar(255) | YES | MUL | NULL | |
| certified_email | varchar(255) | YES | MUL | NULL | |
| website | varchar(255) | YES | MUL | NULL | |
| address | varchar(255) | YES | MUL | NULL | |
| postcode | varchar(255) | YES | MUL | NULL | |
| city_id | varchar(255) | YES | | NULL | |
| facebook_url | varchar(255) | YES | | NULL | |
| twitter_url | varchar(255) | YES | | NULL | |
| email_they_read | tinyint(4) | YES | | 0 | |
| certified_email_they_read | tinyint(4) | YES | | 0 | |
| vip | tinyint(4) | YES | | 0 | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+---------------------------+------------------+------+-----+---------+----------------+
Мы не знаем, как его оптимизировать. Я думаю, что мы включили слишком много условий, и есть более простой способ.
Как мы можем сделать это представление более производительным?