Зачем знать алгоритмы

Содержание

Слайд 2

Who is Mr. Aksenov?

Who is Mr. Aksenov?

Слайд 4

честно листал все!

честно листал все!

Слайд 5

не прочитал ни одной :(

не прочитал ни одной :(

Слайд 7

делал веб-сайты и веб-движок

делал веб-сайты и веб-движок

Слайд 9

делал игры и 3D движок

делал игры и 3D движок

Слайд 12

делаю поисковой движок

делаю поисковой движок

Слайд 13

free open source search

free open source search

Слайд 14

<<

free :(

free :(

Слайд 16

что могу рассказать?

что могу рассказать?

Слайд 17

как устроены всякие движки

как устроены всякие движки

Слайд 19

на пальцах, не по книжке! (см. “не читатель”)

на пальцах, не по книжке! (см. “не читатель”)

Слайд 20

про движок СУБД (любой)

про движок СУБД (любой)

Слайд 21

Система Управления Базой Данных

Система Управления Базой Данных

Слайд 22

данные – это таблицы. из строк

данные – это таблицы. из строк

Слайд 24

строки – нужно где-то хранить

строки – нужно где-то хранить

Слайд 27

это, кстати, данные – без индексов

это, кстати, данные – без индексов

Слайд 28

добавляем PK, и брюки превращаются…

добавляем PK, и брюки превращаются…

Слайд 31

почему так? разные стратегии хранения строк

почему так? разные стратегии хранения строк

Слайд 32

MyISAM – в порядке поступления (в конец файла)

MyISAM – в порядке поступления (в конец файла)

Слайд 33

InnoDB – хранит постранично, внутри странички – в порядке PK

InnoDB – хранит постранично, внутри странички – в порядке PK

Слайд 34

(InnoDB, после добавления PK)

(InnoDB, после добавления PK)

Слайд 35

MyISAM – “обычное” хранение InnoDB – т.н. “кластерное”

MyISAM – “обычное” хранение InnoDB – т.н. “кластерное”

Слайд 36

умеем хранить – теперь нужно быстро искать!

умеем хранить – теперь нужно быстро искать!

Слайд 37

SELECT * FROM users WHERE id=123

SELECT * FROM users WHERE id=123

Слайд 38

SELECT * FROM users WHERE lastname=‘Pupkin’

SELECT * FROM users WHERE lastname=‘Pupkin’

Слайд 39

SELECT * FROM users WHERE lastname LIKE ‘Pu%’

SELECT * FROM users WHERE lastname LIKE ‘Pu%’

Слайд 40

SELECT * FROM goods WHERE MATCH(‘ipod’) ORDER BY price ASC

SELECT * FROM goods WHERE MATCH(‘ipod’) ORDER BY price ASC

Слайд 41

SELECT * FROM users WHERE sex=‘F’ AND age>=18 AND age<=25

SELECT * FROM users WHERE sex=‘F’ AND age>=18 AND age

Слайд 43

как выполнять запрос?

как выполнять запрос?

Слайд 44

полный перебор? мееедленно

полный перебор? мееедленно

Слайд 45

нас спасут…

нас спасут…

Слайд 47

индексы! алгоритмы уже спешат на помощь!

индексы! алгоритмы уже спешат на помощь!

Слайд 48

смысл любого вида индекса?

смысл любого вида индекса?

Слайд 49

быстрый поиск по ключу(-ам)

быстрый поиск по ключу(-ам)

Слайд 55

видов индексов – тоже много

видов индексов – тоже много

Слайд 56

hash index

hash index

Слайд 57

R-tree index

R-tree index

Слайд 58

full-text index

full-text index

Слайд 59

индекс общего назначения – типично B-tree

индекс общего назначения – типично B-tree

Слайд 60

поиск – по равенству, диапазону (чисел, строк, и т.п.)

поиск – по равенству, диапазону (чисел, строк, и т.п.)

Слайд 61

дискует – страничками (хорошо!)

дискует – страничками (хорошо!)

Слайд 62

используется – всеми

используется – всеми

Слайд 67

используется несмотря ни на что!!!

используется несмотря ни на что!!!

Слайд 68

как устроено?

как устроено?

Слайд 69

(B-дерево; странички; масштаб 1:72)

(B-дерево; странички; масштаб 1:72)

Слайд 70

два вида страничек

два вида страничек

Слайд 71

Промежуточные = ключи + указатели на другие странички

{ key1, ptr1, key2, ptr2,

Промежуточные = ключи + указатели на другие странички { key1, ptr1, key2, ptr2, …, keyN }
…, keyN }

Слайд 72

Листовые = ключи + соотв-е им данные (eg. row_offset)

{ key1, data1, key2,

Листовые = ключи + соотв-е им данные (eg. row_offset) { key1, data1, key2, data2, … }
data2, … }

Слайд 73

Промежуточные

Листовые

Промежуточные Листовые

Слайд 74

почему все используют этот ужас?!

почему все используют этот ужас?!

Слайд 75

во-1х – легко искать по ключу

во-1х – легко искать по ключу

Слайд 76

пример – ищем Зину

пример – ищем Зину

Слайд 83

ура – Зина нашлась!!!

ура – Зина нашлась!!!

Слайд 84

хорошо – поиск работает…

хорошо – поиск работает…

Слайд 85

…но он чё, всегда такой резкий?

…но он чё, всегда такой резкий?

Слайд 87

– В жизни – под 1000 (а не 3) записей на страничку –

– В жизни – под 1000 (а не 3) записей на страничку
Два уровня страничек – 1000*1000 – миллион – Три уровня – миллиард… – Итого 2-3 странички max – практически всегда

Слайд 88

почему все используют этот ужас?!

почему все используют этот ужас?!

Слайд 89

во-2х – легко обновлять

во-2х – легко обновлять

Слайд 90

странички обычно НЕ полны

странички обычно НЕ полны

Слайд 91

вставляем…

вставляем…

Слайд 92

вставляем…

вставляем…

Слайд 93

вставляем… оп-па, некуда!!

вставляем… оп-па, некуда!!

Слайд 94

создаем новую страничку

создаем новую страничку

Слайд 95

создаем новую страничку

создаем новую страничку

Слайд 96

…и суем “ее” в родителя

…и суем “ее” в родителя

Слайд 97

это все – тоже трогаем max 2-3 странички

это все – тоже трогаем max 2-3 странички

Слайд 99

B-tree Kung Fu!!!

B-tree Kung Fu!!!

Слайд 100

вернемся к запросам?

вернемся к запросам?

Слайд 101

SELECT * FROM users WHERE id=123

1. “Ищем Зину” (rowoffset по id=123)

2. seek(rowoffset)

SELECT * FROM users WHERE id=123 1. “Ищем Зину” (rowoffset по id=123)
в файле строк (.MYD)

3. read(rowdata) из файла

4. и… все – результат готов

Слайд 102

усложним – добавим условий

усложним – добавим условий

Слайд 103

SELECT * FROM users WHERE sex=‘F’ AND age>=18 AND age<=25

SELECT * FROM users WHERE sex=‘F’ AND age>=18 AND age

Слайд 104

индекс “в лоб” по sex?

индекс “в лоб” по sex?

Слайд 107

они ВСЕ подходят по условию ‘F’!

они ВСЕ подходят по условию ‘F’!

Слайд 109

…и нам надо прочитать с диска (!) 5,000,000+ строк…

…и нам надо прочитать с диска (!) 5,000,000+ строк…

Слайд 110

…и для каждой лично проверить паспорт и age>=18 and age<=25?!

…и для каждой лично проверить паспорт и age>=18 and age

Слайд 112

неселективный индекс – косяк и западло!

неселективный индекс – косяк и западло!

Слайд 113

sex=‘F’ AND age>=18 AND age<=25 индекс “по лбу” по age?

sex=‘F’ AND age>=18 AND age

Слайд 114

но – вдруг это мужики?!

но – вдруг это мужики?!

Слайд 115

мужики нам не нужны!!!

мужики нам не нужны!!!

Слайд 116

либо опять читать ненужные строки (мужиков) – либо…

либо опять читать ненужные строки (мужиков) – либо…

Слайд 117

покрывающий (covering) индекс по обоим полям

покрывающий (covering) индекс по обоим полям

Слайд 119

список нужных строк – ясен сразу

список нужных строк – ясен сразу

Слайд 120

чтений с диска – минимум скорости – максимум

чтений с диска – минимум скорости – максимум

Слайд 121

бонус – сортировка по age

бонус – сортировка по age

Слайд 122

кстати, про сортировку…

кстати, про сортировку…

Слайд 123

SELECT * FROM users WHERE sex=‘F’ AND age>=18 AND age<=25 ORDER BY hotness DESC

SELECT * FROM users WHERE sex=‘F’ AND age>=18 AND age
LIMIT 10

Слайд 124

как выполнять? есть варианты

как выполнять? есть варианты

Слайд 126

налево – read_index(WHERE) + read_rows + sort_rows(ORDER)

налево – read_index(WHERE) + read_rows + sort_rows(ORDER)

Слайд 127

индекс

данные

сортировка

результат

индекс данные сортировка результат

Слайд 128

read_index – мало и быстро

read_index – мало и быстро

Слайд 129

10K*( 1+4+8 bytes ) = 130 KB 5-10 ms/seek, 50+ MB/s read

10K*( 1+4+8 bytes ) = 130 KB 5-10 ms/seek, 50+ MB/s read

Слайд 130

read_random_rows – медленно! 10K*5-10 ms/seek = 50-100 sec…

read_random_rows – медленно! 10K*5-10 ms/seek = 50-100 sec…

Слайд 131

sort_rows – обычно быстро 10K*0.1-1 KB/row = 1-10 MB (in RAM)

sort_rows – обычно быстро 10K*0.1-1 KB/row = 1-10 MB (in RAM)

Слайд 132

мораль – все зло от random rows!

мораль – все зло от random rows!

Слайд 133

(еще от sort_rows, если их много)

(еще от sort_rows, если их много)

Слайд 135

… sex=‘F’ AND age>=18 AND age<=25 ORDER BY hotness DESC LIMIT 10

… sex=‘F’ AND age>=18 AND age

Слайд 136

направо – read_fat_index(WHERE) + sort_index(ORDER) + LIMIT + read_less_rows + sort_rows

направо – read_fat_index(WHERE) + sort_index(ORDER) + LIMIT + read_less_rows + sort_rows

Слайд 137

нужен утолщенный INDEX ( sex, age, hotness )

нужен утолщенный INDEX ( sex, age, hotness )

Слайд 138

вместе с поиском по sex, age – сразу узнаем hotness (+40 KB)

вместе с поиском по sex, age – сразу узнаем hotness (+40 KB)

Слайд 139

sort ( 10K * [ hotness, rowptr ] )

sort ( 10K * [ hotness, rowptr ] )

Слайд 140

read_rows – почти не нужен (10 строк результата…)

read_rows – почти не нужен (10 строк результата…)

Слайд 141

sort_rows – вообще не нужен

sort_rows – вообще не нужен

Слайд 143

не панацея – даже в теории

не панацея – даже в теории

Слайд 144

INDEX ( sex, age, hotness ) WHERE sex=‘F’ ORDER BY hotness LIMIT 10

INDEX ( sex, age, hotness ) WHERE sex=‘F’ ORDER BY hotness LIMIT 10

Слайд 145

в теории – обработать 50% индекса затем – прочитать 10 строк (пф!)

в теории – обработать 50% индекса затем – прочитать 10 строк (пф!)

Слайд 146

INDEX ( sex, age, hotness ) 1M rows, ~20 MB, 50% = ~10

INDEX ( sex, age, hotness ) 1M rows, ~20 MB, 50% = ~10 MB
MB

Слайд 147

INDEX ( sex, age, hotness ) WHERE sex=‘F’ AND hotness>0 ORDER BY age

INDEX ( sex, age, hotness ) WHERE sex=‘F’ AND hotness>0 ORDER BY age LIMIT 10
LIMIT 10

Слайд 148

в теории – читаем индекс линейно – пока не заполним limit

в теории – читаем индекс линейно – пока не заполним limit

Слайд 149

что на практике?

что на практике?

Слайд 150

welcome to real world

welcome to real world

Слайд 151

CREATE TABLE usertest ( id INTEGER PRIMARY KEY NOT NULL, sex ENUM ('m','f'), age

CREATE TABLE usertest ( id INTEGER PRIMARY KEY NOT NULL, sex ENUM
INTEGER NOT NULL, hotness INTEGER NOT NULL, name VARCHAR(255) NOT NULL, INDEX(sex,age,hotness) )

Слайд 152

500,000 записей 56 MB данных (.ibd файл) 32 MB innodb_buffer_pool age \in [18.. 80] hotness \in

500,000 записей 56 MB данных (.ibd файл) 32 MB innodb_buffer_pool age \in
[-5.. 5]

Слайд 153

mysql> explain select * from usertest where sex='f' and age>=18 and age<=25 order by

mysql> explain select * from usertest where sex='f' and age>=18 and age
hotness desc limit 10 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: usertest type: ref possible_keys: sex key: sex key_len: 2 ref: const rows: 25119 Extra: Using where; Using filesort 1 row in set (0.00 sec)

Слайд 154

filesort – НЕ про временный файл filesort – про “сортировку строк”

filesort – НЕ про временный файл filesort – про “сортировку строк”

Слайд 155

Using where – проверка условия НЕ по индексу – ?!!

Using where – проверка условия НЕ по индексу – ?!!

Слайд 156

запрос проще, точно по индексу?

запрос проще, точно по индексу?

Слайд 157

mysql> explain select * from usertest where sex='f' and age=18 order by hotness desc

mysql> explain select * from usertest where sex='f' and age=18 order by
limit 10 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: usertest type: ref possible_keys: sex key: sex key_len: 6 ref: const,const rows: 10386 Extra: Using where (bug #30733, 30 aug 2007?) 1 row in set (0.00 sec)

Слайд 158

проверим экспериментально!!!

проверим экспериментально!!!

Слайд 159

mysql> select * from usertest where sex='f' and age>=18 and age<=25 order by hotness

mysql> select * from usertest where sex='f' and age>=18 and age select
desc limit 10; ... 10 rows in set (23.05 sec) mysql> select * from usertest where sex='f' and age=18 order by hotness desc limit 10; ... 10 rows in set (0.05 sec)

Слайд 160

причина?

причина?

Слайд 161

mysql> explain select * from usertest where sex='f' and age>=18 and age<=25 order by

mysql> explain select * from usertest where sex='f' and age>=18 and age
hotness desc limit 10 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: usertest type: ref possible_keys: sex key: sex key_len: 2 ? используется только начало, поле “sex”!!! ref: const rows: 25119 Extra: Using where; Using filesort ? так и есть :( 1 row in set (0.00 sec)

Слайд 162

MySQL не умеет сортировать элементы индекса :(

MySQL не умеет сортировать элементы индекса :(

Слайд 163

сортировка “по индексу” – только если индекс гарантирует порядок

сортировка “по индексу” – только если индекс гарантирует порядок

Слайд 164

1) в куске индекса sex=F, 18<=age<=25 порядок hotness desc НЕ гарантирован

1) в куске индекса sex=F, 18

Слайд 165

2) optimizer лажанул, 18<=age<=25 считается НЕ по индексу (а могло бы)

2) optimizer лажанул, 18

Слайд 166

(теория говорит – можно лучше!)

(теория говорит – можно лучше!)

Слайд 167

проверяем дальше!

проверяем дальше!

Слайд 168

mysql> explain select * from usertest where sex='f' order by hotness desc limit

mysql> explain select * from usertest where sex='f' order by hotness desc
10 \G ... key: sex key_len: 2 ref: const rows: 226072 Extra: Using where; Using filesort mysql> explain select * from usertest where sex='f' order by hotness desc limit 10 \G ... 10 rows in set (20.25 sec)

Слайд 169

и последний запрос

и последний запрос

Слайд 170

mysql> explain select * from usertest where sex='f' and hotness>0 order by

mysql> explain select * from usertest where sex='f' and hotness>0 order by
age asc limit 10 \G ... key: sex key_len: 2 ref: const rows: 226072 Extra: Using where; Using filesort mysql> select * from usertest where sex='f' and hotness>0 order by age asc limit 10; ... 10 rows in set (0.25 sec)

Слайд 171

итого

итого

Слайд 172

теория была оптимистична…

теория была оптимистична…

Слайд 173

…реальность внесла коррективы.

…реальность внесла коррективы.

Слайд 174

не учли детали реализации

не учли детали реализации

Слайд 175

1. нету “досортировки” индекса (MySQL specific)

1. нету “досортировки” индекса (MySQL specific)

Слайд 176

2. limit обрабатывается… так себе (MySQL specific)

2. limit обрабатывается… так себе (MySQL specific)

Слайд 177

3. optimizer ошибается (везде и у всех)

3. optimizer ошибается (везде и у всех)

Слайд 178

про ошибки optimizer и спасительный full-scan

про ошибки optimizer и спасительный full-scan

Слайд 179

mysql> select * from usertest where sex='f' order by hotness desc limit

mysql> select * from usertest where sex='f' order by hotness desc limit
10; ... 10 rows in set (20.25 sec) mysql> select * from usertest ignore index(sex) where sex='f' order by hotness desc limit 10; ... 10 rows in set (0.55 sec)

Слайд 180

10,000 x 10 ms = 100 sec 100,000 x 1KB / 50 M/s

10,000 x 10 ms = 100 sec 100,000 x 1KB / 50 M/s = 2 sec
= 2 sec

Слайд 181

мораль: random IO очень плохо (водка яд водка яд водка яд)

мораль: random IO очень плохо (водка яд водка яд водка яд)

Слайд 182

про “обработку” limit

про “обработку” limit

Слайд 183

теория – приоритетная очередь

теория – приоритетная очередь

Слайд 186

технически – heap

технически – heap

Слайд 188

или просто double buffer

или просто double buffer

Слайд 191

ключевое свойство – в памяти храним только top-N

ключевое свойство – в памяти храним только top-N

Слайд 192

LIMIT 10 – надо хранить 10 строк

LIMIT 10 – надо хранить 10 строк

Слайд 193

LIMIT 130,10 – надо 140

LIMIT 130,10 – надо 140

Слайд 194

практика – MySQL vs. LIMIT

практика – MySQL vs. LIMIT

Слайд 195

выбрать и отсортировать ВСЕ (*)

* – всегда, когда индекс не гарантирует точный

выбрать и отсортировать ВСЕ (*) * – всегда, когда индекс не гарантирует точный порядок
порядок

Слайд 196

выбрать OK – избежать нельзя

выбрать OK – избежать нельзя

Слайд 198

сортировать все плохо…

сортировать все плохо…

Слайд 200

лишний удар по CPU/RAM/IO :(

лишний удар по CPU/RAM/IO :(

Слайд 201

как убирать mysql сортировку?

как убирать mysql сортировку?

Слайд 202

строить более другие индексы

строить более другие индексы

Слайд 203

ставить более другой софт

ставить более другой софт

Слайд 204

умеет и “обычный” поиск!

умеет и “обычный” поиск!

Слайд 205

трюки про WHERE вместо LIMIT (я не пробовал, но говорят, возможно)

трюки про WHERE вместо LIMIT (я не пробовал, но говорят, возможно)

Слайд 206

…именно в таком порядке.

…именно в таком порядке.

Слайд 207

более практический пример?

более практический пример?

Слайд 208

импортируем дамп Wikipedia

импортируем дамп Wikipedia

Слайд 209

XML дамп → 2 толстые таблицы хочется – а) одну б) тонкую!

XML дамп → 2 толстые таблицы хочется – а) одну б) тонкую!

Слайд 210

INSERT INTO mycontent SELECT t.old_id, p.page_id, UNIX_TIMESTAMP(p.page_touched), p.page_len, p.page_title, COMPRESS(t.old_text) FROM text t, page

INSERT INTO mycontent SELECT t.old_id, p.page_id, UNIX_TIMESTAMP(p.page_touched), p.page_len, p.page_title, COMPRESS(t.old_text) FROM text
p WHERE t.old_id=p.page_latest AND page_namespace=0 AND page_is_redirect=0; 15 GB text, 0.5 GB page, ~4.5M rows tps=~200, bi/bo=~1 MB/sec ~200 MB .MYD in ~20 mins, ETA 10+ hrs

Слайд 211

mysql> EXPLAIN SELECT t.old_id, ... \G ********************** 1. row ********************** table: page type:

mysql> EXPLAIN SELECT t.old_id, ... \G ********************** 1. row ********************** table: page
ref key: name_title ref: const rows: 4435392 Extra: Using where ********************** 2. row ********************** table: text type: eq_ref key: PRIMARY ref: wiki.p.page_latest rows: 1

Слайд 212

что хотим? scan 15 GB text, join 0.5 GB page

что хотим? scan 15 GB text, join 0.5 GB page

Слайд 213

почему не выходит? … FROM text t, page p WHERE t.old_id=p.page_latest

почему не выходит? … FROM text t, page p WHERE t.old_id=p.page_latest

Слайд 214

решение – index(page_latest)

решение – index(page_latest)

Слайд 215

еще пришлось STRAIGHT_JOIN (optimizer опять лажанул!)

еще пришлось STRAIGHT_JOIN (optimizer опять лажанул!)

Слайд 216

результат – 40 минут, включая CREATE INDEX

результат – 40 минут, включая CREATE INDEX

Слайд 218

так зачем же знать алгоритмы?

так зачем же знать алгоритмы?

Слайд 219

“did we learn something today?”

“did we learn something today?”

Слайд 221

как устроено B-дерево

как устроено B-дерево

Слайд 222

как работает индекс

как работает индекс

Слайд 223

как работают выборки

как работают выборки

Слайд 224

зачем нужны full-scans

зачем нужны full-scans

Слайд 225

как работает сортировка с LIMIT

как работает сортировка с LIMIT

Слайд 226

чего можно добиться в идеале – в теории

чего можно добиться в идеале – в теории

Слайд 227

…и как оно, бывает, не работает – на практике!

…и как оно, бывает, не работает – на практике!

Слайд 228

а толку?!

а толку?!

Слайд 229

чего ждать от БД

чего ждать от БД

Слайд 230

чего не ждать

чего не ждать

Слайд 231

как и что тестировать

как и что тестировать

Слайд 232

как объяснять потом результаты

как объяснять потом результаты

Слайд 234

в итоге – как заставлять таки работать

в итоге – как заставлять таки работать

Слайд 236

…БЫСТРО работать.

…БЫСТРО работать.
Имя файла: Зачем-знать-алгоритмы.pptx
Количество просмотров: 107
Количество скачиваний: 0