Обновить

Комментарии 6

Насколько я могу видеть, никакой специальной предварительной индексации для фасетов не делается. Тогда, если базовый запрос сматчит миллионы записей, например, пользователь не ограничит выборку по бренду или другим существенным параметрам, весь этот миллион и будет пропускаться через каждый фасет. У вас есть планы по дальнейшей оптимизации подобных сценариев?

На 1 миллионе записей это займёт несколько миллисекунд:

 ~  manticore-load --quiet \
--drop \
--batch-size=1000 \
--threads=5 \
--total=1000000 \
--init="CREATE TABLE test(id bigint, name text, type int)" \
--load="INSERT INTO test(id,name,type) VALUES(<increment>,'abc',<int/1/10>)"

Threads ; Batch     ; Time        ; Total Docs  ; Docs/Sec    ; Avg QPS     ; p99 QPS     ; p95 QPS     ; p5 QPS      ; p1 QPS      ; Lat Avg     ; Lat p50     ; Lat p95     ; Lat p99     ;
5       ; 1000      ; 00:01       ; 1000000     ; 920889      ; 938         ; 938         ; 938         ; 938         ; 938         ; 5.4         ; 4.5         ; 8.5         ; 9.5         ;
 ~  mysql -P9306 -h0 -e "select * from test where match('abc') facet type; show meta;"
+--------+------+------+
| id     | name | type |
+--------+------+------+
| 362001 | abc  |    5 |
| 800001 | abc  |    8 |
| 800002 | abc  |    1 |
| 362002 | abc  |    4 |
| 800003 | abc  |    1 |
| 362003 | abc  |    4 |
| 362004 | abc  |    5 |
| 800004 | abc  |    4 |
| 362005 | abc  |    2 |
| 800005 | abc  |    2 |
| 362006 | abc  |    7 |
| 800006 | abc  |   10 |
| 362007 | abc  |   10 |
| 800007 | abc  |    5 |
| 362008 | abc  |    4 |
| 800008 | abc  |    4 |
| 362009 | abc  |    8 |
| 800009 | abc  |    6 |
| 362010 | abc  |    5 |
| 800010 | abc  |    1 |
+--------+------+------+
+------+----------+
| type | count(*) |
+------+----------+
|    5 |   100058 |
|    8 |   100089 |
|    4 |    99950 |
|    1 |    99778 |
|    2 |    99780 |
|    7 |    99737 |
|   10 |   100247 |
|    6 |    99745 |
|    9 |   100534 |
|    3 |   100082 |
+------+----------+
+----------------+---------+
| Variable_name  | Value   |
+----------------+---------+
| total          | 20      |
| total_found    | 1000000 |
| total_relation | eq      |
| time           | 0.009   |
| multiplier     | 2       |
| keyword[0]     | abc     |
| docs[0]        | 1000000 |
| hits[0]        | 1000000 |
+----------------+---------+
 ~  mysql -P9306 -h0 -e "select * from test where match('abc') and type=5 limit 0 OPTION facet_filter_mode='auto' facet type; show meta;"
+------+----------+-----------+
| type | count(*) | status    |
+------+----------+-----------+
|    5 |   100058 | selected  |
|    8 |   100089 | available |
|    4 |    99950 | available |
|    1 |    99778 | available |
|    2 |    99780 | available |
|    7 |    99737 | available |
|   10 |   100247 | available |
|    6 |    99745 | available |
|    9 |   100534 | available |
|    3 |   100082 | available |
+------+----------+-----------+
+----------------+---------+
| Variable_name  | Value   |
+----------------+---------+
| total          | 0       |
| total_found    | 100058  |
| total_relation | eq      |
| time           | 0.013   |
| keyword[0]     | abc     |
| docs[0]        | 1000000 |
| hits[0]        | 1000000 |
+----------------+---------+


И на 10 миллионах всё ещё терпимо

 ~  mysql -P9306 -h0 -e "select * from test where match('abc') and type=5 limit 0 OPTION facet_filter_mode='auto' facet type; show meta;"
+------+----------+-----------+
| type | count(*) | status    |
+------+----------+-----------+
|    7 |  1000018 | available |
|    4 |   999817 | available |
|    2 |  1000507 | available |
|    6 |  1000134 | available |
|    9 |   999282 | available |
|    5 |   999624 | selected  |
|    3 |  1000269 | available |
|    8 |  1000087 | available |
|   10 |   999891 | available |
|    1 |  1000371 | available |
+------+----------+-----------+
+----------------+----------+
| Variable_name  | Value    |
+----------------+----------+
| total          | 0        |
| total_found    | 999624   |
| total_relation | eq       |
| time           | 0.082    |
| keyword[0]     | abc      |
| docs[0]        | 10000000 |
| hits[0]        | 10000000 |
+----------------+----------+


Для одного низкокардинального фасета, конечно, ничего делать и не нужно, но что, если кардинальность будет сильно больше? И если фасетов будет не один, а множество? У вас же сложность O(M * K), где M — количество сматченных документов, K — число фасетов. То есть 4 фасета должны дать увеличение времени где-то в 4 раза. Хотя, конечно, это всё ещё будут миллисекунды.

Около 0.7 сек можно ожидать на 100М документов и 3 фасетах. И это когда все 100М фасетятся, что маловероятно.

 ~  mysql -P9306 -h0 -e "select * from test where match('abc') limit 0 facet type facet type2 facet s; show meta;"
+------+----------+
| type | count(*) |
+------+----------+
|    8 | 10001461 |
|    5 | 10000328 |
|    7 |  9996859 |
|    9 |  9997826 |
|    2 | 10001818 |
|   10 |  9999687 |
|    6 | 10005232 |
|    1 | 10001297 |
|    3 | 10000901 |
|    4 |  9994591 |
+------+----------+
+-------+----------+
| type2 | count(*) |
+-------+----------+
|     9 |  9996891 |
|     5 | 10001193 |
|     4 | 10000757 |
|     2 |  9998652 |
|     7 | 10002256 |
|    10 | 10003231 |
|     8 | 10001287 |
|     1 |  9995331 |
|     6 | 10000138 |
|     3 | 10000264 |
+-------+----------+
+------+----------+
| s    | count(*) |
+------+----------+
| j    |  3843350 |
| w    |  3846258 |
| t    |  3845736 |
| y    |  3846464 |
| p    |  3847130 |
| v    |  3844940 |
| c    |  3846880 |
| n    |  3845483 |
| a    |  3847138 |
| z    |  3842557 |
| k    |  3847765 |
| m    |  3846786 |
| o    |  3843457 |
| g    |  3845203 |
| i    |  3843668 |
| u    |  3847252 |
| h    |  3848362 |
| e    |  3845783 |
| d    |  3842085 |
| f    |  3846935 |
+------+----------+
+----------------+-----------+
| Variable_name  | Value     |
+----------------+-----------+
| total          | 0         |
| total_found    | 100000000 |
| total_relation | eq        |
| time           | 0.783     |
| multiplier     | 4         |
| keyword[0]     | abc       |
| docs[0]        | 100000000 |
| hits[0]        | 100000000 |
+----------------+-----------+


Большое спасибо. Действительно очень неплохие результаты. А можно, если вас не затруднит, посмотреть на этакий «корнер-кейс»: фасет по полю с очень высокой кардинальностью, например миллионы или десятки миллионов? Понимаю, что на практике это вряд ли случится, но просто интересно, как движок себя поведёт. Аналогично для строкового поля с высокой кардинальностью.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации