У меня возникли проблемы с показателями и производительностью моего запроса.
В настоящее время я делаю следующее:
SELECT
images.imageId,
path,
fileName,
alt,
description,
width,
height
FROM
images
LEFT JOIN imagesEn ON images.imageId=imagesEn.imageId
WHERE
images.adId = ?
AND images.imageStatus = 1
AND images.isPreview = 1
AND (images.isBanner = 0 OR images.isBanner IS NULL)
ORDER BY RAND() LIMIT 1;';
Это дает мне изображение, которое я хочу. Но я использую адаптивные элементы изображения, есть меньшие версии изображения.
Мои ограниченные знания sql заставили меня использовать другой запрос, например, так:
SELECT
images.imageId,
relativePathToImageFromImgFolder,
fileName,
altAttribute,
description,
width,
height
FROM
images
LEFT JOIN imagesEn ON images.imageId=imagesEn.imageId
WHERE
images.adId = ?
AND images.imageStatus = 1
AND images.isPreview = 0
AND images.isSmallerVersionOf = ?
ORDER by width DESC
Затем я заканчиваю двумя запросами и двумя массивами, которые дают мне основное изображение плюс все меньшие версии изображения для создания элемента моей картинки.
Объединение необходимо, потому что у меня есть несколько языков (imagesEn, imagesDe, imagesFr и т. Д.), Которые соединяют имя файла, атрибуты на данном языке.
Я только что установил одностолбцевые индексы, многостолбцовые индексы для меня новы, о которых я слышал впервые за сегодня: D.
Я показываю что-то вроде producte на странице продукта, и мое время генерации страницы составляет около 0,3 секунд (без обналичивания). Все остальные мои страницы имеют 0,0x секунды, что также является моей целью для этой страницы.
Плюс я делаю этот запрос внутри цикла
$query = 'SELECT name, id, url, whatever from products where productColor = "blue";';
foreach($arr as $r)
{
$str .= '<div>';
$str .= $r['name'] . ' ' . $r['whatever'];
$str .= self::createPictureElementFromId($r['id']); //this calls the above queries to create the picture element with its main image and the child images (smaller versions for smaller screens)
$str .= '</div>';
}
return $str;
Надеюсь, описание достаточно точное;).
заранее спасибо
Попробуй с этим. Он объединяет два раза таблицу изображений (один для обычного изображения и второй для уменьшенной версии, если она существует), и два раза — таблицу ImageEn, которая должна иметь перевод описания и другие вещи.
Если вы ищете только одно изображение, ваше время БД не будет намного лучше.
Псевдоним таблиц в полях выбора должен быть неправильным, потому что я не знаю, где это каждое поле. Описание должно быть на imagesEn и imagesEn2
Это только одна меньшая версия изображения. Если у вас есть много небольших изображений, вы можете присоединиться к таблице изображений в три раза, но ИМХО, это должно быть чище, чем вы делаете это сейчас, в вашем коде с двумя вариантами выбора.
SELECT
i.imageId,
i.path,
i.fileName,
i.alt,
i.description,
i.width,
i.height,
i2.relativePathToImageFromImgFolder,
i2.fileName,
i2.altAttribute,
i2.description,
i2.width,
i2.height
FROM
images as i
LEFT JOIN imagesEn as iEn ON i.imageId=iEn.imageId
LEFT JOIN images as i2 on ((i2.isSmallerVersionOf = i.imageID) AND (i2.imageStatus = 1) AND (i2.isPreview = 0))
LEFT JOIN imagesEn2 as IEn2 ON i2.imageId = iEn2.imageId
WHERE
i2.adId = ?
AND i.imageStatus = 1
AND i.isPreview = 1
AND (i.isBanner = 0 OR i.isBanner IS NULL)
ORDER BY RAND() LIMIT 1;
i.isBanner = 0 OR i.isBanner IS NULL
— Выбери один. Это позволит вам избавиться от OR
, который является убийцей производительности.
Тогда есть INDEX(adId, imageStatus, isPreview, isBanner)
(в любом порядке). Это должно позволить фильтрации работать быстрее.
Пожалуйста предоставьте SHOW CREATE TABLE
, так как я должен угадать некоторые из ваших типов данных и т. д.
Сделать ORDER BY RAND() LIMIT 1
, неэффективно перемещаться вокруг всех столбцов, только чтобы выбрать один из них. Итак, вместо этого сделайте это:
SELECT i.imageId, i.path, ...
FROM ( SELECT imageId FROM images WHERE ...
ORDER BY RAND() LIMIT 1 ) AS x
JOIN images i USING(imageId)
Но тогда вам нужно INDEX(adId, imageStatus, isPreview, isBanner, imageId)
так что внутренний запрос может выполняться полностью в индексе.
«Меньшая версия» — пусть флаг скажет «это маленькое изображение» и включите его в WHERE
и INDEX
,
Язык URL — Добавить еще один JOIN
чтобы получить языковой URL, который должен быть в другой стол. Эта таблица должна иметь PRIMARY KEY(imageId, lang)
,