Skip to content

Conversation

@danf0rth
Copy link

@danf0rth danf0rth commented Jun 29, 2018

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

Что изменилось и зачем это нужно:

  • теперь не используется JOIN + DISTINCT на огромной результирущей таблице, теперь мы сперва делаем выборку всех товаров в нужных нам категориях, затем делаем DISTINCT, после чего выбираем по ID этих товаров из таблицы shop_product
    • запрос выполняется в 20 раз быстрее, если раньше на 80к товаров это было 1.84 сек., сейчас - 0.09 сек. (Delta -95.10%)
    • вместе с этим, теперь быстрее выполняется запрос на подсчет количества товаров: раньше - 0.27 сек., сейчас - 0.13 сек. (Delta -51.85%)
    • теперь не используется using temporary, using_filesort, в результате чего снижается дисковое I/O
  • мелкий рефакторинг, код для генерации алиаса вынесет в отдельный метод generateAliasForTable

Количество данных:
shop_product: 82066
shop_category_products: 165121

ВАЖНО: т.к. код не покрыт тестами, быстро проверить работоспособность невозможно. Немного потыкал, посравнивал результаты запросов - визуально все ок, нужно смотреть детальней
ВАЖНО: этот PR зависит от этого, т.к. используется метод waDbQuery::getSQL(), который должен быть публичным.
ВАЖНО: производительность на маленьких таблицах не мерил, там, где JOIN + DISTINCT может влезть в буфер, запрос теоретически может работать быстрее, но не на столько, на сколько выигрывает в скорости на больших данных запрос из этого PR.

Есть небольшие косяки в PHPDoc, чуть позже поправлю.

@Leonix, @SergeR, @ZloyTip, @WinterSilence

По мотивам этой темы: https://support.webasyst.ru/27218/medlennaya-skorost-raboty-s-bolshim-kolichestvo-tovarov-pravit-dvizhok-/

danf0rth added 3 commits June 28, 2018 11:45
…imes faster

Немного изменена логика запроса в БД. Теперь, вместо того чтобы JOIN-ть большие таблицы, мы сначала делаем выборку товаров, присутствующих в нужных
категориях, а затем эту выборку JOIN-им с shop_product таблицей. Что это нам дает:

	* отпимизатор больше не использует using_temporary, using_filesort, из-за этого снижается дисковая нагрузка
	* обычный запрос (без ручной сортировки) выполняется на 95% быстрее (20-кратное ускорение), если раньше на 80к товаров это было 1.84 сек, сейчас - 0.09 сек.
	* также ускорился COUNT запрос
	* в ручной сортировке также немного ускорился запрос, т.к. DISTINCT делается в простом подзапросе без джойнов, когда результирующий размер таблицы ещё не такой большой и влезает в буфер

Также был проделан небольшой рефакторинг, например, получение алиаса таблицы вынесено в отдельный метод.

ВНИМАНИЕ: так как код не покрыт тестами, нет никаких гарантий что где-то что-то не всплывет. Поэтому, нужно тщательно проверить.
@SergeR
Copy link
Contributor

SergeR commented Dec 7, 2018

Очень надеюсь, что это будет в основном коде. Хоть когда-нибудь 😢

@danf0rth
Copy link
Author

danf0rth commented Dec 7, 2018

@SergeR в идеале, переделать логику хранения товаров в категориях как я описал тут. Так будет на порядок быстрее и проще делать выборки, без IN(), DISTINCT, смс и регистраций.

То что в этом PR это скорее временная мера для жирных магазинов.

@SergeR
Copy link
Contributor

SergeR commented Dec 7, 2018

@SergeR в идеале, переделать логику хранения товаров в категориях как я описал тут. Так будет на порядок быстрее и проще делать выборки, без IN(), DISTINCT, смс и регистраций.

То что в этом PR это скорее временная мера для жирных магазинов.

Держать дубли товаров -- это вообще не по феншую совсем.

@WinterSilence
Copy link
Contributor

@SergeR мы говорим о реляционных субд, а конкретнее про мускул, поэтому при большой нагрузке дублирование данных выгоднее номализации. Учи мат.часть.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants