Хм, ну теоретически вполне возможно, что вы правы (я вот к примеру не могу назвать себя специалистом в данной области). Но тогда было бы неплохо получить от вас конкретные рекомендации по БД КБ, где именно Вы бы добавили индексы.


какие на данный момент есть советы по Ускорению работы базы
Автор smart, 17 сент. 2011 08:55
Сообщений в теме: 21
#21
Отправлено 02 Февраль 2015 - 18:12
#22
Отправлено 02 Февраль 2015 - 18:50
CbCoder (02 Февраль 2015 - 18:12) писал:
... было бы неплохо получить от вас конкретные рекомендации по БД КБ, где именно Вы бы добавили индексы.
С пользовательскими таблицами дать какие то общие однозначные рекомендации дать не возможно. Слишком разный у всех набор таблиц и полей.
По "служебным" таблицам, типа f_acc_, f_tips и т.д.- попробую найти одну из конфигураций, где заказчик согласился оплатить работу по оптимизации и индексированию. Эта работа, как в песне "И на первый взгляд как буд-то не видна..." но требует долгого и тщательного анализа. Сейчас сразу уже не вспомню всего. Но поделюсь общими пожеланиями.
При отслеживании запросов, обратил внимание на следующее.
Одни и те же запросы к базе, собирающие практически одни и те же данные, но с разных страниц приложения, написаны по разному. В частности, условия отбора одинаковы, но последовательность их отличаются.
Например (условно, на самом деле запросы значительно сложнее, с JOIN ами - скрытыми или явными)
SELECT * FROM `f_dataXXX` WHERE `fYYY` = 0 AND `fZZZ`= 'Значение' AND `status` = 0
Тот же запрос, но на другой странице приложения
SELECT * FROM `f_dataXXX` WHERE `status` = 0 AND `fZZZ`= 'Значение' AND `fYYY` = 0
Обратите внимание на порядок перечисления условий.
Для каждого такого запроса будут нужны разные индексы. А что мешало написать их одинаково? И Индексов потребовалось бы меньше.
Вообще, любой SQL сервер обрабатывает условия в следующем порядке
Сначала последнее условие, затем, предпоследнее и т.д. И индексы нужно строить исходя из этого
Так вот, в первом случае нужны составные индексы по полям (в порядке , обратном перечислению условий).
status_fZZZ_fYYY
а во втором - fYYY_fZZZ_status
Пример условный. Злоупотреблять этим тоже не good. Каждый индекс следует проверять на профайлере, или хотя бы с помощью EXPLAIN SELECT (что мало, но все же) . Лишние индексы только зря увеличат размер базы и замедлят работу в случае вставки или обновления таблиц
Ну и следует смотреть, чтобы не было FULL SCAN, JOIN' ов по не индексированным столбцам, FILE SORT, USE TEMPORARY и т.д. К сожалению, в коротком посте всего не расскажешь. Да и не это было целью. Я хотел, чтобы на это наконец обратили внимание. А соответстствующих материалов в том же google масса
Ну, как то так
Да, это уже к пользователям. Не злоупотребляйте вычислениями с условием "Отображение" поля. Забудьте про него.
Представьте себе, у вас есть такое поле и вы открываете страницу, на которой 100 записей, каждая из которых содержит вычисление на "отображение". Система 100 раз "отобразит" и 100 раз запустит вычисление. А если оно еще и с рекурсией...
Если уж никак без такого не обойтись, то в режиме таблицы НЕ ПОКАЗЫВАЙТЕ это поле. По крайней мере сбережете ресурсы.
Ну и после того, как закончите с индексацией, дайте немного поработать серверу, набрать статистики и сделайте запрос, чтобы определить малоэффективные индексы, которые можро смело убить
SELECT t.TABLE_SCHEMA AS `db`, t.TABLE_NAME AS `table`, s.INDEX_NAME AS `inde name`, s.COLUMN_NAME AS `field name`, s.SEQ_IN_INDEX `seq in index`, s2.max_columns AS `# cols`, s.CARDINALITY AS `card`, t.TABLE_ROWS AS `est rows`, ROUND(((s.CARDINALITY / IFNULL(t.TABLE_ROWS, 0.01)) * 100), 2) AS `sel %` FROM INFORMATION_SCHEMA.STATISTICS s INNER JOIN INFORMATION_SCHEMA.TABLES t ON s.TABLE_SCHEMA = t.TABLE_SCHEMA AND s.TABLE_NAME = t.TABLE_NAME INNER JOIN (SELECT TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, MAX(SEQ_IN_INDEX) AS max_columns FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA != 'mysql' GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME) AS s2 ON s.TABLE_SCHEMA = s2.TABLE_SCHEMA AND s.TABLE_NAME = s2.TABLE_NAME AND s.INDEX_NAME = s2.INDEX_NAME WHERE t.TABLE_SCHEMA != 'mysql' AND t.TABLE_ROWS > 10 AND s.CARDINALITY IS NOT NULL AND (s.CARDINALITY / IFNULL(t.TABLE_ROWS, 0.01)) < 1.00 ORDER BY `sel %`, s.TABLE_SCHEMA, s.TABLE_NAME LIMIT 10
Сообщение отредактировал maksn: 02 Февраль 2015 - 20:23
Количество пользователей, читающих эту тему: 1
0 пользователей, 1 гостей, 0 анонимных