2015-08-11 6 views
0

В настоящее время я пишу инструкцию SQL для выбора часового пояса для конкретной страны в базе данных настроек Prestashop. Таблицы я использую являются:MySQL query optimization prestashop

  • ps_timezone: часовой пояс (Канада/Atlantic, Америка/Adak и т.д.)
  • ps_country_lang: Название страны (Канада, Соединенные государства, france и т. д.)
  • ps_country: country table (Я использовал его, так как знаю страну, но хочу знать ее зону).
  • ps_zone: зона (Америка, Европа, Азия, и т.д.)

И я написал следующий запрос (id_country = 4 Канада):

SELECT tz.id_timezone, tz.name FROM ps_timezone tz WHERE tz.name LIKE CONCAT((SELECT cl.name FROM ps_country_lang cl WHERE cl.id_country=4 and cl.id_lang = 1) ,'%') OR tz.name LIKE CONCAT((SELECT CASE WHEN INSTR(z.name, 'Europe') > 0 THEN 'Europe' WHEN INSTR(z.name, 'America') > 0 THEN 'America' ELSE z.name END as zone_name FROM ps_zone z JOIN ps_country c ON z.id_zone = c.id_zone WHERE c.id_country =4), '%') ORDER BY CASE WHEN tz.name LIKE CONCAT((SELECT cl.name FROM ps_country_lang cl WHERE cl.id_country=4 and cl.id_lang = 1) ,'%') THEN 1 ELSE 2 END, tz.name ASC; 

Запрос работает нормально, но я бы хотел, чтобы советы пожилых людей касались оптимизации моих личных улучшений и культуры.

Во-первых, я с помощью LIKE, чтобы проверить, начинается ли часовой пояс с названием страны:

tz.name LIKE CONCAT((SELECT cl.name FROM ps_country_lang cl WHERE cl.id_country=4 and cl.id_lang = 1) ,'%') 

или имя зоны:

tz.name LIKE CONCAT((SELECT CASE WHEN INSTR(z.name, 'Europe') > 0 THEN 'Europe' WHEN INSTR(z.name, 'America') > 0 THEN 'America' ELSE z.name END as zone_name FROM ps_zone z JOIN ps_country c ON z.id_zone = c.id_zone WHERE c.id_country =4), '%') 

Я подозревающих, что ключевое слово LIKE не является наиболее результативным ... было бы более эффективным извлечь первую часть часового пояса и сравнить его прямо так:

WHERE LEFT(tz.name, INSTR(tz.name, "/") - 1) = (SELECT cl.name FROM ps_country_lang cl WHERE cl.id_country=4 and cl.id_lang = 1) 

Во-вторых, я использую SELECT в ORDER BY, поэтому сначала отображается часовой пояс с именем страны.

ORDER BY CASE WHEN tz.name LIKE CONCAT((SELECT cl.name FROM ps_country_lang cl WHERE cl.id_country=4 and cl.id_lang = 1) ,'%') THEN 1 ELSE 2 END, tz.name ASC 

Конечно, это эстетический вопрос, но я беспокоюсь о проблемах с производительностью. Будет ли запрос запускаться только один раз, поскольку он использует фиксированные значения (я знаю идентификатор страны перед отправкой запроса в базу данных, а язык должен всегда 1 для английского) или будет выполняться для каждой строки?

Кроме того, мне это не очень нравится, поскольку у меня есть тот же самый подзапрос как в предложении WHERE, так и в предложениях ORDER BY. Я не могу использовать псевдоним из предложения SELECT, поскольку предложение WHERE выполняется первым (в любом случае это заставило бы меня бесполезно возвращать строку).

Конечно, лучший курс делать то, было бы для меня, чтобы исключить временную зону с именем континента, если у меня есть часовой пояс для страны ...

Я в сознании тех, кто нет простых вопросов, но думаю, что они являются интересным вопросом для многих юниоров, как и я, серьезно относиться к обучению правильному программированию.

Спасибо,

Джонатан Parent-Левеку из Монреаля

ответ

2

Я бы упростить этот запрос, воспользовавшись DateTimeZone PHP компоненты, введенной в PHP 5.2, который возвращает идентификаторы часового пояса для данного ISO 3166-1 страны кода (например, «CA» для Канады).

Пример:

<?php 

$country_iso_code = 'CA'; 
$timezone = DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $country_iso_code); 

echo $timezone[0]; /* Multiple timezones per country, get the 1st one */ 
+0

Если бы это было мое собственное кодирование, я бы использовал это решение наверняка, но PrestaShop является электронной коммерции платформы, на которой разработчики могут добавлять собственные модули. Мой личный опыт в области импорта данных из моего другого программного обеспечения Boss (GEM-CAR) заключается в том, что небольшое изменение/упущение в структуре данных заставляет Prestashop не работать (например, учетная запись пользователя не работает, если вы ставите пустой строка как фамилия). Вот почему я использую этот сложный запрос для извлечения предустановленного часового пояса. Но, я с удовольствием рассмотрю это решение для своих личных проектов. Спасибо –

+0

В PrestaShop мы построили таблицу MySQL ps_timezone для единственной предпосылки правильной установки функции date_default_timezone_set() в config/config.inc.php. Эта таблица является чистым отражением DateTimeZone :: listIdentifiers(), которая в то время не существовала и не привязана к стране или зонам. Вот почему я предлагаю использовать класс DateTimeZone PHP и иметь полностью разделенный код, кроме ядра PrestaShop. –