2009-02-12 3 views
0

Вот сценарий 1.Оптимизировать процесс поиска MySQL

У меня есть таблица под названием «элементы», внутри таблица имеет 2 колонки, д. г. item_id и item_name. Я храню данные таким образом: item_id | item_name

Ss001 | Shirt1 
Sb002 | Shirt2 
Tb001 | TShirt1 
Tm002 | TShirt2 

... и т.д., я хранить таким образом: первой буква кода для одежды, то есть S для рубашки, T для тенниски второго письма размера, т.е. s для малых, м для среднего и b для больших Давайте скажем, что в моей таблице предметов я получил 10 000 предметов. Я хочу сделать быстро получить, позволяет сказать, что я хочу, чтобы найти определенную рубашку, я могу использовать:

Method1:

SELECT * from items WHERE item_id LIKE Sb99; 

или я должен сделать это нравится:

Method2:

SELECT * from items WHERE item_id LIKE S*; 

* Сохраните результат, затем выполните второй поиск размера, затем третий поиск идентификатора. Как и концепция хэш-таблицы. То, что я хочу достичь, вместо поиска всех данных, я хочу свести к минимуму поиск путем поиска кода одежды сначала, следуйте по размеру кода, а затем по идентификационному коду. Какой из них лучше с точки зрения скорости в mysql. И какой из них лучше в долгосрочной перспективе. Я хочу уменьшить трафик и не беспокоить базу данных так часто.

Спасибо, ребята, за решение моего первого сценария. Но другой сценарий приходит в:

Сценарий 2:

Я использую PHP и MySQL. Продолжайте рассказ. Если моя пользователи структура таблицы выглядит так:

user_id | username | items_collected 

U0001 | Alex  | Ss001;Tm002 
U0002 | Daniel | Tb001;Sb002 
U0003 | Michael | ... 
U0004 | Thomas | ... 

Я хранить items_collected в виде идентификатора, потому что один день каждый пользователь может получить до сотни пунктов, если хранить в виде строки, т.е. Shirt1, pants2, ..., для этого потребовалось бы очень большое количество пространств баз данных (представьте, если у нас 1000 пользователей, а некоторые элементы - очень длинные).

Было бы проще сохранить, если я сохраню в виде id?

И если позволяет сказать, я хочу отобразить изображение, а имя изображения - это имя элемента + jpg. Как это сделать? Это что-то вроде этого:

$ Результат = Выберите items_collected от пользователей, где UserID = $ Идентификатор_пользователя

Использование PHP взрываются:

$ itemsCollected = взорваться ($ результат, ";");

После этого, соответствие каждого элемента в таблице пунктов, поэтому он хотел бы:

shirt1, pants2 и т.д.

Ден с помощью функции петли, петли каждое значение и добавить «.jpg», чтобы отобразить изображение ?

+0

для точного соответствия вы можете: WHERE item_id = 'Sb99' (не забывайте котировки) – tehvan

ответ

3

Первый способ будет быстрее - но ИМО это не правильный способ сделать это. Я согласен с техваном об этом.

Я бы рекомендовал держать в ITEM_ID как есть, но добавить два дополнительных поля одно для кода и один для размера, то вы можете сделать:

select * from items where item_code = 'S' and item_size = 'm' 

С индексами производительность будет значительно увеличена, и вы сможете легко соответствовать диапазону размеров или кодов.

select * from items where item_code = 'S' and item_size IN ('m','s') 

Перенесите дб следующим образом:

alter table items add column item_code varchar(1) default ''; 
alter table items add column item_size varchar(1) default ''; 

update items set item_code = SUBSTRING(item_id, 1, 1); 
update items set item_size = SUBSTRING(item_id, 2, 1); 

Изменения в коде должны быть столь же просто добавить. Долгосрочная выгода будет стоить усилий.


Для сценария 2 - это не эффективный способ хранения и извлечения данных из базы данных. При использовании таким образом база данных действует только как механизм хранения, путем кодирования нескольких данных в поля, которые исключают возможность использования реляционной части базы данных.

Что вы должны сделать в этом случае, это иметь другую таблицу, назовите ее «items_collected». Схема была бы вдоль линий

CREATE TABLE items_collected (
    id int(11) NOT NULL auto_increment KEY, 
    userid int(11) NOT NULL, 
    item_code varchar(10) NOT NULL, 
    FOREIGN KEY (`userid`) REFERENCES `user`(`id`), 
    FOREIGN KEY (`itemcode`) REFERENCES `items`(`item_code`) 
); 

внешние ключи гарантируют, что есть Referential integrity, важно to have referential integrity.

Тогда для примера, который вы дадите, у вас будет несколько записей.

user_id | username | items_collected 
U0001 | Alex  | Ss001 
U0001 | Alex  | Tm002 
U0002 | Daniel | Sb002 
U0002 | Daniel | Tb001 
U0003 | Michael | ... 
U0004 | Thomas | ... 
+0

позволяет сказать, что мои данные недостаточно велики, должен ли я использовать индексы ?? – roa3

+0

Для небольших значений огромных вам не нужны индексы - однако, если данные в основном статичны, то даже с несколькими (<100) строками это стоит того. Подготовьте «EXPLAIN» на выбор, чтобы увидеть, что происходит. –

1

Первая оптимизация будет расколоть идентификатор в трех различных областях: один для типов, один для размера, один для текущего идентификатора заканчивающегося (безотносительно заканчивающиеся средства) Если вы действительно хотите сохранить текущую структуру, перейти для результата сразу (вариант 1).

1

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

Шаг 2 - создать индекс для каждого столбца. Помните, что mysql использует только один индекс для каждой таблицы для каждого запроса. Поэтому, если вам действительно нужны быстрые запросы, и ваши запросы сильно отличаются от этих свойств, вам может понадобиться создать индекс (тип, размер, конец), (тип, конец, размер) и т. Д.

Например, запрос с

select * from items where type = s and size = s and ending = 001 

может извлечь выгоду из индекса (тип, размер, окончание), но:

select * from items where size = s and ending = 001 

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

Еще одно замечание, как правило, не рекомендуется использовать * в запросах, но выбирать только нужные столбцы.

1

Вы должны иметь три колонки для model, size и id, и индекс их таким образом:

CREATE INDEX ix_1 ON (model, size, id) 
CREATE INDEX ix_2 ON (size, id) 
CREATE INDEX ix_3 ON (id, model) 

Тогда вы будете в состоянии эффективно искать на любое подмножество параметров:

  • model-size-id, model-size и model запросы будут использовать ix_1;
  • size-id и size запросы будут использовать ix_2;
  • model-id и id запросы будут использовать индекс ix_3

на вашей колонке, как это теперь эквивалентно ix_1, и вы можете использовать этот индекс для эффективного поиска на соответствующих условиях (model-size-id, model-size и model).

На самом деле существует определенный путь доступа, называемый INDEX SKIN SCAN, который может использоваться для поиска по непервым столбцам составного индекса, но MySQL не поддерживает его AFAIK.


Если вам нужно придерживаться вашего текущего дизайна, вам нужно индексировать поля и использовать запросы, как:

WHERE item_id LIKE @model || '%' 
WHERE item_id LIKE @model || @size || '%' 
WHERE item_id = @model || @size || @id 

Все эти запросы будут использовать индекс, если таковые имеются.

Не нужно вводить несколько запросов.

0

Мне комфортно, что вы разработали свой item_id для поиска с помощью теста «Начинается с». Индексы будут быстро решены для вас.

Я не знаю MySQL, но в MSSQL, имеющем индекс в столбце «Размер», который имеет только выбор S, M, L, скорее всего, ничего не добьется, индекс не будет использоваться, потому что содержащиеся в нем значения недостаточно избирательны, то есть быстрее, чем просто просматривать все данные, а не «найти первую запись S в индексе, теперь извлекать страницу данных для этой строки ...»

Исключение составляет запрос покрывается индексом - то есть в индекс включены несколько частей предложения WHERE (и действительно, все из них, а также столбцы SELECT). В этом случае, однако, первое поле в индексе (в MSSQL) должно быть выборочным. Поэтому сначала поставьте столбец с самыми разными значениями в индексе.

Сказав, что если ваше приложение имеет список выбора для размера, цвета и т. Д., Вы должны иметь эти атрибуты данных в отдельных столбцах в записи - и отдельные таблицы со списками всех доступных цветов и размеров, а затем вы можете подтвердите, что Цвет/Размер, заданный Продукту, фактически определен в Таблицах Цвет/Размер. Сбрасывает проблему с мусором/мусором!

Ваш элемент должен быть в отдельной таблице, чтобы он был «нормализован».Не храните список с ограничителями в одном столбце, сохраните его, используя отдельные строки в отдельной таблице

Таким образом, ваша таблица USERS содержит user_id & имени пользователя

Ваши, новая, items_collected таблицы содержат user_id & ITEM_ID (и, возможно, дату покупки или номер счета)

Затем вы можете сказать «Что сделал Алекс» (ваш дизайн имеет это), а также «Кто купил Ss001» (который в вашем дизайне потребует вспашки по всем рядам в таблице USERS и расщеплении items_collected, чтобы найти, какие из них содержат Ss001 [1])

[1] Следует отметить, что с помощью LIKE не будет действительно безопасным для этого, потому что вы могли бы иметь ITEM_ID из «Ss001XXX», который соответствовал бы КУДА items_collected LIKE «% SS001%»

Смежные вопросы