Какие распространенные ошибки при разработке баз данных делают разработчики приложений?
database
database-design
Charles Faiga
источник
источник
Ответы:
1. Не использовать соответствующие индексы
Это относительно легко, но все же это происходит постоянно. Внешние ключи должны иметь индексы на них. Если вы используете поле в a,
WHERE
вы должны (вероятно) иметь индекс на нем. Такие индексы часто должны охватывать несколько столбцов на основе запросов, которые необходимо выполнить.2. Не обеспечивает ссылочную целостность
Здесь ваша база данных может отличаться, но если ваша база данных поддерживает ссылочную целостность - это означает, что все внешние ключи гарантированно указывают на существующую сущность - вы должны использовать ее.
Довольно часто можно увидеть этот сбой в базах данных MySQL. Я не верю, что MyISAM это поддерживает. InnoDB делает. Вы найдете людей, которые используют MyISAM или тех, кто использует InnoDB, но не использует его в любом случае.
Больше здесь:
3. Использование естественных, а не суррогатных (технических) первичных ключей
Естественные ключи - это ключи, основанные на внешне значимых данных, которые (якобы) уникальны. Типичными примерами являются коды продуктов, двухбуквенные коды штатов (США), номера социального страхования и так далее. Суррогатные или технические первичные ключи - это те, которые не имеют абсолютно никакого значения вне системы. Они придуманы исключительно для идентификации объекта и, как правило, представляют собой автоматически увеличивающиеся поля (SQL Server, MySQL и т. Д.) Или последовательности (в первую очередь Oracle).
На мой взгляд, вы всегда должны использовать суррогатные ключи. Эта проблема возникла в следующих вопросах:
Это довольно спорная тема, по которой вы не получите универсального согласия. Хотя вы можете найти некоторых людей, которые думают, что естественные ключи в некоторых ситуациях хороши, вы не найдете никакой критики за суррогатные ключи, за исключением того, что они, возможно, не нужны. Это довольно маленький недостаток, если вы спросите меня.
Помните, что даже страны могут прекратить свое существование (например, Югославия).
4. Написание запросов, требующих
DISTINCT
работыВы часто видите это в ORM-сгенерированных запросах. Посмотрите на вывод журнала из Hibernate, и вы увидите, что все запросы начинаются с:
Это своего рода быстрый способ убедиться, что вы не возвращаете дублирующиеся строки и, следовательно, не получаете дублирующиеся объекты. Иногда вы увидите, как люди делают это. Если вы видите это слишком много, это настоящий красный флаг. Не так
DISTINCT
уж плохо или не имеет действительных приложений. Это делает (по обоим пунктам), но это не суррогат или временная пробел для написания правильных запросов.От того, почему я ненавижу DISTINCT :
5. Предпочтение агрегации над объединениями
Другая распространенная ошибка разработчиков приложений баз данных заключается в том, что они не понимают, насколько более дорогая агрегация (т.
GROUP BY
Е. Предложение) может быть сравнена с объединениями.Чтобы дать вам представление о том, насколько это широко распространено, я несколько раз писал на эту тему здесь, и за это меня сильно опровергли. Например:
Из оператора SQL - «присоединиться» к «группировать и иметь» :
6. Не упрощать сложные запросы через представления
Не все поставщики баз данных поддерживают представления, но те, которые поддерживают, могут значительно упростить запросы, если их использовать разумно. Например, в одном проекте я использовал общую модель Party для CRM. Это чрезвычайно мощный и гибкий метод моделирования, но он может привести ко многим соединениям. В этой модели было:
Пример:
Таким образом, есть пять таблиц, соединенных, чтобы связать Теда с его работодателем. Вы предполагаете, что все сотрудники - Персоны (не организации) и предоставляете это вспомогательное представление:
И вдруг вы получаете очень простое представление нужных вам данных, но в очень гибкой модели данных.
7. Не дезинфицирующий ввод
Это огромный. Теперь мне нравится PHP, но если вы не знаете, что делаете, очень легко создавать сайты, уязвимые для атак. Ничто не суммирует это лучше, чем история маленьких столиков Бобби .
Данные, предоставленные пользователем посредством URL-адресов, данных формы и файлов cookie, всегда должны рассматриваться как враждебные и очищенные. Убедитесь, что вы получаете то, что ожидаете.
8. Не использовать готовые заявления
Подготовленные операторы - это когда вы компилируете запрос за вычетом данных, используемых во вставках, обновлениях и
WHERE
предложениях, а затем предоставляете их позже. Например:против
или
в зависимости от вашей платформы.
Я видел базы данных, поставленные на колени при этом. По сути, каждый раз, когда любая современная база данных встречает новый запрос, она должна его скомпилировать. Если он встречает запрос, который видел раньше, вы даете базе данных возможность кэшировать скомпилированный запрос и план выполнения. Делая много запросов, вы даете базе данных возможность выяснить это и оптимизировать соответствующим образом (например, закрепив скомпилированный запрос в памяти).
Использование подготовленных утверждений также даст вам значимую статистику о том, как часто используются определенные запросы.
Подготовленные операторы также лучше защитят вас от атак SQL-инъекций.
9. Не достаточно нормализуется
Нормализация базы данных - это в основном процесс оптимизации структуры базы данных или того, как вы организуете свои данные в таблицы.
Только на этой неделе я наткнулся на какой-то код, где кто-то взорвал массив и вставил его в одно поле в базе данных. Нормализуя это, можно было бы рассматривать элемент этого массива как отдельную строку в дочерней таблице (т. Е. Отношение «один ко многим»).
Это также появилось в методе Best для хранения списка идентификаторов пользователей :
Но отсутствие нормализации проявляется во многих формах.
Больше:
10. Нормализация слишком много
Это может показаться противоречием предыдущему пункту, но нормализация, как и многие другие, является инструментом. Это средство для достижения цели, а не самоцель. Я думаю, что многие разработчики забывают об этом и начинают воспринимать «средства» как «цели». Модульное тестирование является ярким примером этого.
Однажды я работал над системой, которая имела огромную иерархию для клиентов, которая имела вид:
так что вам нужно было объединить около 11 таблиц, прежде чем вы смогли получить какие-либо значимые данные. Это был хороший пример нормализации, зашедшей слишком далеко.
Точнее говоря, осторожная и продуманная денормализация может иметь огромные преимущества в производительности, но вы должны быть очень осторожны при этом.
Больше:
11. Использование эксклюзивных дуг
Исключительная дуга является распространенной ошибкой, когда таблица создается с двумя или более внешними ключами, где один и только один из них может быть ненулевым. Большая ошибка. С одной стороны, становится намного сложнее поддерживать целостность данных. В конце концов, даже при ссылочной целостности ничто не препятствует установке двух или более этих внешних ключей (несмотря на сложные ограничения проверки).
Из практического руководства по проектированию реляционных баз данных :
12. Не анализировать производительность по запросам вообще
Прагматизм царит, особенно в мире баз данных. Если вы придерживаетесь принципов до такой степени, что они стали догмой, вы, вероятно, допустили ошибки. Возьмите пример совокупных запросов сверху. Совокупная версия может выглядеть «красиво», но ее производительность ужасна. Сравнение производительности должно было закончить дискуссию (но не сделало этого), но более конкретно: высказывание таких плохо информированных взглядов, во-первых, невежественно, даже опасно.
13. Чрезмерная зависимость от конструкций UNION ALL и особенно UNION
Термины UNION в SQL просто объединяют конгруэнтные наборы данных, что означает, что они имеют одинаковый тип и количество столбцов. Разница между ними заключается в том, что UNION ALL - это простая конкатенация, и ее следует использовать везде, где это возможно, тогда как UNION будет неявно выполнять DISTINCT для удаления дублирующихся кортежей.
Союзы, как DISTINCT, имеют свое место. Есть действительные заявки. Но если вы обнаружите, что делаете много из них, особенно в подзапросах, то вы, вероятно, делаете что-то не так. Это может быть причиной плохой конструкции запроса или плохо разработанной модели данных, которая заставляет вас делать такие вещи.
UNION, особенно когда они используются в соединениях или зависимых подзапросах, могут нанести вред базе данных. Старайтесь избегать их, когда это возможно.
14. Использование условий OR в запросах
Это может показаться безвредным. В конце концов, И все в порядке. ИЛИ должно быть тоже хорошо? Неправильно. По существу, условие AND ограничивает набор данных, тогда как условие OR увеличивает его, но не таким образом, чтобы его можно было оптимизировать. В частности, когда различные условия ИЛИ могут пересекаться, вынуждая оптимизатор эффективно выполнять операцию DISTINCT для результата.
Плохой:
Лучше:
Теперь ваш оптимизатор SQL может эффективно превратить первый запрос во второй. Но это не так. Просто не делай этого.
15. Не разрабатывать свою модель данных для использования в высокопроизводительных решениях.
Это трудная точка для количественной оценки. Это обычно наблюдается по его эффекту. Если вы обнаружите, что пишете грубые запросы для относительно простых задач или что запросы для поиска относительно простой информации неэффективны, то, вероятно, у вас плохая модель данных.
В некотором смысле этот пункт суммирует все предыдущие, но это скорее предостерегающий рассказ о том, что такие вещи, как оптимизация запросов, часто выполняются первыми, а потом вторыми. Прежде всего вы должны убедиться, что у вас есть хорошая модель данных, прежде чем пытаться оптимизировать производительность. Как сказал Кнут:
16. Неправильное использование транзакций базы данных
Все изменения данных для конкретного процесса должны быть атомарными. Т.е. если операция прошла успешно, она делает это полностью. Если это не удается, данные остаются без изменений. - Не должно быть возможности «полусделанных» изменений.
В идеале, самый простой способ добиться этого - вся система должна стремиться поддерживать все изменения данных с помощью одного оператора INSERT / UPDATE / DELETE. В этом случае не требуется никакой специальной обработки транзакций, поскольку ваша база данных должна делать это автоматически.
Однако, если какие-либо процессы требуют, чтобы несколько операторов выполнялись как единое целое для поддержания данных в согласованном состоянии, тогда необходим соответствующий контроль транзакций.
Также рекомендуется обратить пристальное внимание на тонкости того, как ваш слой подключения к базе данных и ядро базы данных взаимодействуют в этом отношении.
17. Непонимание парадигмы на основе множеств
Язык SQL следует определенной парадигме, подходящей для конкретных задач. Несмотря на различные специфичные для поставщика расширения, язык борется с проблемами, которые тривиальны в таких языках, как Java, C #, Delphi и т. Д.
Это отсутствие понимания проявляется в нескольких отношениях.
Определите четкое разделение ответственности и постарайтесь использовать соответствующий инструмент для решения каждой проблемы.
источник
Ключевые ошибки в дизайне и программировании базы данных, сделанные разработчиками
Эгоистичный дизайн и использование базы данных. Разработчики часто рассматривают базу данных как свое личное постоянное хранилище объектов, не учитывая потребности других заинтересованных сторон в данных. Это также относится к разработчикам приложений. Плохая структура базы данных и целостность данных затрудняют работу с данными третьих сторон и могут существенно увеличить затраты на жизненный цикл системы. Отчеты и MIS имеют тенденцию быть плохим кузеном в разработке приложений и делаются только в качестве запоздалой мысли.
Злоупотребление денормализованными данными. Чрезмерное превышение денормализованных данных и попытка сохранить их в приложении - это рецепт для проблем целостности данных. Используйте денормализацию экономно. Отсутствие необходимости добавлять объединение в запрос не является оправданием для денормализации.
Боится писать SQL. SQL не является ракетостроением и на самом деле довольно хорошо справляется со своей работой. Уровни O / R-отображения достаточно хороши для выполнения 95% простых запросов, которые хорошо вписываются в эту модель. Иногда SQL - лучший способ сделать эту работу.
Догматические политики «Нет хранимых процедур». Независимо от того, считаете ли вы хранимые процедуры злыми, такого рода догматическому отношению нет места в программном проекте.
Не понимая дизайн базы данных. Нормализация - твой друг, и это не ракетостроение. Объединение и кардинальность - довольно простые понятия - если вы вовлечены в разработку приложений для баз данных, то на самом деле нет оправдания тому, что они не понимают.
источник
источник
Чрезмерное использование и / или зависимость от хранимых процедур.
Некоторые разработчики приложений рассматривают хранимые процедуры как прямое расширение кода среднего уровня / внешнего интерфейса. Похоже, что это общая черта разработчиков стека Microsoft (я один из них, но я вырос из этого) и создает много хранимых процедур, которые выполняют сложную бизнес-логику и обработку рабочих процессов. Это гораздо лучше сделано в другом месте.
Хранимые процедуры полезны, когда фактически доказано, что некоторые реальные технические факторы требуют их использования (например, производительность и безопасность). Например, хранение агрегации / фильтрации больших наборов данных «близко к данным».
Недавно мне пришлось помогать поддерживать и улучшать большое настольное приложение Delphi, 70% бизнес-логики и правил которого были реализованы в 1400 хранимых процедурах SQL Server (остальное в обработчиках событий пользовательского интерфейса). Это был кошмар, в первую очередь из-за сложности внедрения эффективного модульного тестирования в TSQL, отсутствия инкапсуляции и плохих инструментов (отладчики, редакторы).
Работая с командой Java в прошлом, я быстро обнаружил, что в этой среде часто встречается полная противоположность. Архитектор Java однажды сказал мне: «База данных предназначена для данных, а не для кода».
В наши дни я считаю ошибкой вообще не учитывать хранимые процедуры, но их следует использовать экономно (не по умолчанию) в ситуациях, когда они дают полезные преимущества (см. Другие ответы).
источник
Проблема номер один? Они тестируют только на игрушечных базах. Поэтому они понятия не имеют, что их SQL будет сканироваться, когда база данных станет больше, и кто-то должен прийти и починить ее позже (этот звук, который вы можете услышать, - мои зубы скрипят).
источник
Не используя индексы.
источник
Низкая производительность, вызванная коррелированными подзапросами
Большую часть времени вы хотите избежать коррелированных подзапросов. Подзапрос коррелируется, если в подзапросе есть ссылка на столбец из внешнего запроса. Когда это происходит, подзапрос выполняется по крайней мере один раз для каждой возвращенной строки и может выполняться несколько раз, если применяются другие условия после применения условия, содержащего коррелированный подзапрос.
Простите за надуманный пример и синтаксис Oracle, но, скажем, вы хотели найти всех сотрудников, которые были наняты в любом из ваших магазинов с тех пор, как в последний раз магазин совершал менее 10 000 долларов продаж в день.
Подзапрос в этом примере соотносится с внешним запросом store_id и будет выполняться для каждого сотрудника вашей системы. Одним из способов оптимизации этого запроса является перемещение подзапроса во встроенное представление.
В этом примере запрос в предложении from теперь является встроенным представлением (опять же с определенным синтаксисом Oracle) и выполняется только один раз. В зависимости от вашей модели данных этот запрос, вероятно, будет выполняться намного быстрее. Это будет работать лучше, чем первый запрос, так как количество сотрудников растет. Первый запрос мог бы работать лучше, если бы было мало сотрудников и много магазинов (и, возможно, во многих магазинах не было сотрудников), а таблица daily_sales была проиндексирована на store_id. Это маловероятный сценарий, но показывает, как коррелированный запрос может работать лучше, чем альтернативный.
Я видел, как начинающие разработчики коррелировали подзапросы много раз, и это обычно оказывало серьезное влияние на производительность. Однако при удалении коррелированного подзапроса обязательно просмотрите план объяснения до и после, чтобы убедиться, что производительность не ухудшится.
источник
По моему опыту:
не общаюсь с опытными администраторами баз данных.
источник
Использование Access вместо «настоящей» базы данных. Существует множество отличных небольших и даже бесплатных баз данных, таких как SQL Express , MySQL и SQLite, которые будут работать и масштабироваться намного лучше. Приложения часто нужно масштабировать неожиданными способами.
источник
Забыв установить отношения между таблицами. Я помню, что мне приходилось убирать это, когда я впервые начал работать у моего нынешнего работодателя.
источник
Использование Excel для хранения (огромных объемов) данных.
Я видел компании, которые держат тысячи строк и используют несколько таблиц (из-за ограничения числа строк в 65535 в предыдущих версиях Excel).
Excel хорошо подходит для отчетов, представления данных и других задач, но не должен рассматриваться как база данных.
источник
Я хотел бы добавить: Любимый "элегантный" код по сравнению с высокопроизводительным кодом. Код, который лучше всего работает с базами данных, часто уродлив для глаз разработчиков приложений.
Полагая, что глупость о преждевременной оптимизации. Базы данных должны учитывать производительность в оригинальном проекте и при любой последующей разработке. На мой взгляд, производительность составляет 50% от дизайна базы данных (40% - это целостность данных, а последние 10% - безопасность). Базы данных, которые не созданы снизу вверх для работы, будут работать плохо, когда реальные пользователи и реальный трафик будут размещены в базе данных. Преждевременная оптимизация не означает никакой оптимизации! Это не означает, что вы должны писать код, который почти всегда будет работать плохо, потому что вам будет проще (например, курсоры, которые никогда не должны быть разрешены в производственной базе данных, если все остальное не сработало). Это означает, что вам не нужно смотреть на выжатие последней части производительности, пока вам это не понадобится. Много известно о том, что будет лучше работать с базами данных,
источник
Не использует параметризованные запросы. Они очень удобны для остановки SQL-инъекций .
Это конкретный пример не санации входных данных, упомянутый в другом ответе.
источник
Я ненавижу, когда разработчики используют вложенные операторы select или даже функции, возвращающие результат оператора select внутри части запроса «SELECT».
Я на самом деле удивлен, что не вижу этого где-то еще здесь, возможно, я упустил это из виду, хотя у @adam указана похожая проблема.
Пример:
В этом случае, если MyTable возвращает 10000 строк, результат будет таким, как если бы запрос только что выполнил 20001 запрос, так как он должен был выполнить начальный запрос и запросить каждую из других таблиц один раз для каждой строки результата.
Разработчики могут справиться с этой работой в среде разработки, где они возвращают только несколько строк данных, а вложенные таблицы обычно содержат только небольшой объем данных, но в производственной среде этот вид запроса может стать экспоненциально дорогостоящим, так как больше данные добавляются в таблицы.
Лучшим (не обязательно идеальным) примером будет что-то вроде:
Это позволяет оптимизаторам базы данных перемешивать данные вместе, а не запрашивать каждую запись из основной таблицы, и я обычно нахожу, что когда мне нужно исправить код, в котором была создана эта проблема, я обычно заканчиваю тем, что увеличиваю скорость запросов на 100% или больше, одновременно уменьшая использование процессора и памяти.
источник
Для баз данных на основе SQL:
... еще предстоит добавить.
источник
Не делать резервных копий до исправления некоторых проблем в производственной базе данных.
Использование команд DDL для хранимых объектов (таких как таблицы, представления) в хранимых процедурах.
Боязнь использования хранимых процедур или боязнь использования ORM-запросов там, где они более эффективны / целесообразны.
Игнорирование использования профилировщика базы данных, который может точно сказать, во что в конечном итоге преобразуется ваш запрос ORM, и, следовательно, проверить логику или даже отладку, если не используется ORM.
источник
Не делает правильный уровень нормализации . Вы хотите убедиться, что данные не дублируются, и что вы разбиваете данные на разные по мере необходимости. Вы также должны убедиться, что вы не следуете нормализации слишком далеко, так как это повредит производительности.
источник
Рассматривая базу данных как просто механизм хранения (т.е. прославленную библиотеку коллекций) и, следовательно, подчиняя их приложению (игнорируя другие приложения, которые совместно используют данные)
источник
источник
1 - Излишне использовать функцию для значения в предложении where, а результат этого индекса не используется.
Пример:
вместо
И в меньшей степени: не добавлять функциональные индексы к тем значениям, которые в них нуждаются ...
2 - Не добавлять проверочные ограничения, чтобы обеспечить достоверность данных. Ограничения могут использоваться оптимизатором запросов, и они ДЕЙСТВИТЕЛЬНО помогают гарантировать, что вы можете доверять своим инвариантам. Там просто нет причин, чтобы не использовать их.
3 - Добавление ненормализованных столбцов в таблицы из-за чистой лени или нехватки времени. Вещи обычно не спроектированы таким образом, но развиваются в это. Конечным результатом, без сомнения, является тонна работы, пытающейся навести порядок, когда вас укусила потеря целостности данных в будущих изменениях.
Подумайте об этом, таблицу без данных очень дешево перепроектировать. Таблица с несколькими миллионами записей без какой-либо целостности ... не так уж и дешево перепроектировать. Таким образом, выполнение правильного дизайна при создании столбца или таблицы амортизируется в пики.
4 - не столько о самой базе данных, но действительно раздражает. Не заботясь о качестве кода SQL. Тот факт, что ваш SQL выражен в тексте, не позволяет скрыть логику в кучах алгоритмов манипулирования строками. Вполне возможно написать SQL в тексте способом, который действительно читается вашим коллегой-программистом.
источник
Это было сказано ранее, но: индексы, индексы, индексы . Я видел очень много случаев неэффективных корпоративных веб-приложений, которые были исправлены, просто выполнив небольшое профилирование (чтобы увидеть, какие таблицы часто посещаются), а затем добавив индекс для этих таблиц. Это даже не требует особых знаний в области написания SQL, а отдача огромна.
Избегайте дублирования данных, таких как чума. Некоторые люди защищают, что небольшое дублирование не повредит, и улучшит работу. Эй, я не говорю, что вы должны пытать свою схему в третьей нормальной форме, пока она не станет настолько абстрактной, что даже администратор базы данных не будет знать, что происходит. Просто поймите, что всякий раз, когда вы дублируете набор имен, почтовых индексов или отгрузочных кодов, копии в конечном итоге не синхронизируются друг с другом. Это случится. И тогда вы будете пинать себя, когда будете запускать скрипт еженедельного обслуживания.
И наконец: используйте четкое, последовательное, интуитивно понятное соглашение об именах. Точно так же, как хорошо написанный фрагмент кода должен быть читаемым, хорошая схема или запрос SQL должны быть читаемыми и практически сообщать вам, что они делают, даже без комментариев. Вы будете благодарить себя через шесть месяцев, когда вам придется проводить техническое обслуживание на столах.
"SELECT account_number, billing_date FROM national_accounts"
работать с ним бесконечно проще, чем с «SELECT ACCNTNBR, BILLDAT FROM NTNLACCTS»источник
Не выполняется соответствующий запрос SELECT перед выполнением запроса DELETE (особенно в производственных базах данных)!
источник
Самая распространенная ошибка, которую я видел за двадцать лет: не планировать заранее. Многие разработчики создают базу данных и таблицы, а затем постоянно изменяют и расширяют таблицы по мере создания приложений. Конечный результат часто является беспорядочным и неэффективным, и его трудно убрать или упростить позже.
источник
а) Жесткое кодирование значений запроса в строке.
б) Помещение кода запроса базы данных в действие «OnButtonPress» в приложении Windows Forms.
Я видел оба.
источник
Не уделяйте достаточного внимания управлению соединениями с базой данных в вашем приложении. Затем вы обнаружите, что приложение, компьютер, сервер и сеть забиты.
источник
Думая, что они администраторы баз данных и разработчики моделей данных, когда у них нет формальной идеологической обработки в этих областях.
Думая, что их проект не требует DBA, потому что все это легко / тривиально.
Неправильное разграничение между работой, которая должна выполняться в базе данных, и работой, которая должна выполняться в приложении.
Не проверять резервные копии или не создавать резервные копии.
Встраивание сырого SQL в их код.
источник
Вот ссылка на видео под названием « Классические ошибки при разработке баз данных и пять способов их преодоления » Скотта Вальца.
источник
Отсутствие понимания модели параллелизма баз данных и того, как это влияет на развитие. После факта легко добавлять индексы и настраивать запросы. Однако приложения, разработанные без должного учета горячих точек, конфликта ресурсов и правильной работы (при условии, что то, что вы только что прочитали, все еще действительны!), Могут потребовать значительных изменений в базе данных и уровне приложения, чтобы исправить их позже.
источник
Не понимая, как работает СУБД под капотом.
Вы не можете правильно управлять палкой, не понимая, как работает сцепление. И вы не можете понять, как использовать базу данных, не понимая, что на самом деле вы просто пишете в файл на своем жестком диске.
В частности:
Вы знаете, что такое кластерный индекс? Вы думали об этом, когда разрабатывали свою схему?
Вы знаете, как правильно использовать индексы? Как повторно использовать индекс? Вы знаете, что такое индекс покрытия?
Так здорово, у вас есть индексы. Насколько велика 1 строка в вашем индексе? Насколько большим будет индекс, когда у вас много данных? Это легко впишется в память? Если это не так, это бесполезно в качестве индекса.
Вы когда-нибудь использовали EXPLAIN в MySQL? Отлично. Теперь будьте честны с собой: вы поняли хотя бы половину увиденного? Нет, ты, вероятно, не сделал. Исправь это.
Вы понимаете Query Cache? Знаете ли вы, что делает запрос не кэшируемым?
Вы используете MyISAM? Если вам нужен полнотекстовый поиск, MyISAM все равно дерьмо. Используйте Сфинкса. Затем переключитесь на Inno.
источник
источник