Требуется совет относительно того, могу ли я улучшить свои операторы базы данных или мне следует начать кэширование результатов запросов для повышения производительности.
Схема настроена как Много-ко-многим Полиморф c отношения. У меня есть таблица Videos
, которая содержит видеоинформацию, таблица Category
, которая содержит все категории, и таблица Categorizable
, которая содержит сводную информацию.
Соотношение между Videos
и Categorizable
около 1: 4. (Т.е. для каждого видео есть как минимум 4+ категории).
Результаты при доступе к сводным данным с ограничением в 40 строк и БЕЗ смещения: ~ 1.2s +, Добавление смещения увеличило бы это еще больше, если смещение> 50 000 строк.
Хотя 1,2 секунды кажутся маленькими, это лишь малая часть всего набора данных, который в конечном итоге содержит около 30 миллионов видеозаписей (таким образом, имея ~ 12 + миллион классифицируемых записей). Боюсь, что 1,2 будет умножаться на каждый миллион записей.
Схема базы данных
Таблица видео :
------------------------------------------------------------------------
id | title | author | views | duration | etc.
------------------------------------------------------------------------
1 | What's the biggest word? | Dictonary | 3432 | 600 | ...
2 | Yearly Videos Roundup 2020 | YouTube | 165 | 945 | ...
3 | Google SEO Help | Google | 1401 | 287 | ...
↓
101234 | How to cook pasta | YouTube | 9401 | 87 | ...
Индексы:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
videos | 0 | PRIMARY | 1 | id | A | 253057 | NULL | NULL | | BTREE | | | YES | NULL
videos | 1 | idx_videos_views | 1 | views | A | 102188 | NULL | NULL |YES | BTREE | | | YES | NULL
Таблица категорий :
-------------------------------------------------------------
id | category_id | cateogrizable_id | categorizable_type
-------------------------------------------------------------
1 | 5 | 1 | 'Video'
2 | 100 | 2 | 'Video'
3 | 31 | 3 | 'Video'
↓
299052 | 65 | 101234 | 'Video'
Индексы:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
categorizables | 0 | PRIMARY | 1 | id | A | 296745 | NULL | NULL | | BTREE | | | YES | NULL
categorizables | 1 | idx_category_id | 1 | category_id | A | 82 | NULL | NULL | | BTREE | | | YES | NULL
categorizables | 1 | idx_categorizable_id | 1 | categorizable_id | A | 104705 | NULL | NULL | | BTREE | | | YES | NULL
Таблица категорий :
--------------------
id | name
--------------------
1 | Education
2 | Health
3 | Entertainment
↓
100 | News
Индексы:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
categories | 0 | PRIMARY | 1 | id | A | 100 | NULL | NULL | | BTREE | | | YES | NULL
MySQL
Тип: InnoDB
Laravel Запрос :
Category::where('id', $cat)
->with(['videos' => function($query){
return $query->take(40)->orderby('views');
}])
->get();
Превращается в MySQL запрос :
SELECT `videos`.`id`, `views`
FROM `videos` inner join `categorizables`
ON `videos`.`id` = `categorizables`.`categorizable_id`
WHERE `categorizables`.`category_id` = 1
ORDER BY `views` desc
LIMIT 40 offset 0
Результаты производительности
Ниже приведены выходные данные производительности от MySQL
---------------------------------------------------------
Stage | Duration
---------------------------------------------------------
stage/sql/starting | 0.000068
stage/sql/Executing hook on transaction begin. | 0.000000
stage/sql/starting | 0.000003
stage/sql/checking permissions | 0.000001
stage/sql/checking permissions | 0.000001
stage/sql/Opening tables | 0.000038
stage/sql/init | 0.000003
stage/sql/System lock | 0.000005
stage/sql/optimizing | 0.000007
stage/sql/statistics | 0.005628
stage/sql/preparing | 0.000008
stage/sql/Creating tmp table | 0.000033
stage/sql/executing | 1.273442
stage/sql/end | 0.000001
stage/sql/query end | 0.000001
stage/sql/waiting for handler commit | 0.000008
stage/sql/removing tmp table | 0.000003
stage/sql/closing tables | 0.000006
stage/sql/freeing items | 0.000080
stage/sql/cleaning up | 0.000000
Специально :
stage/sql/executing | 1.273442
Стоимость запроса :
----------------------------------
Variable_name | Value
----------------------------------
Last_query_cost | 107258.575124
РЕДАКТИРОВАТЬ:
Объяснить запрос
С сортировкой:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 | SIMPLE | categorizables | NULL | ref | idx_category_id,idx_categorizable_id | idx_category_id | 4 | const | 51210 | 100.00 | Using temporary; Using filesort
1 | SIMPLE | videos | NULL | eq_ref | PRIMARY | PRIMARY | 4 | dev_db.categorizables.categorizable_id | 1 | 100.00 | Using index
Без сортировки:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 | SIMPLE | videos | NULL | index | NULL | PRIMARY | 4 | NULL | 40 | 100.00 | Backward index scan; Using index