Улучшить производительность запросов Mysql Select [duplicate]

== проверяет ссылки на объекты, .equals() проверяет строковые значения.

Иногда кажется, что == сравнивает значения, потому что Java делает некоторые закулисные вещи, чтобы убедиться, что одинаковые строки в строке являются одним и тем же объектом.

Для Например:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

Но будьте осторожны с нулями!

== обрабатывает строки null в порядке, но вызов .equals() из пустой строки приведет к исключению:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

Итак, если вы знаете, что fooString1 может но не менее очевидно, что он проверяет значение null (из Java 7):

System.out.print(Objects.equals(fooString1, "bar"));
174
задан kmonsoor 12 December 2017 в 10:30
поделиться

7 ответов

В целом, индексы помогают ускорить поиск базы данных, имея недостаток использования дополнительного дискового пространства и замедления запросов INSERT / UPDATE / DELETE. Используйте EXPLAIN и прочитайте результаты, чтобы узнать, когда MySQL использует ваши индексы.

Если таблица имеет шесть столбцов, и все они доступны для поиска, я должен индексировать их все или ни один из них ?

Индексирование всех шести столбцов не всегда является лучшей практикой.

(a) Собираетесь ли вы использовать любой из этих столбцов при поиске конкретной информации?

(b) Какова избирательность этих столбцов (сколько различных значений хранится по сравнению с общим количеством записей в таблице)?

MySQL использует калькулятор, основанный на оптимизации, который пытается найти «самый дешевый» путь при выполнении запроса. И поля с низкой селективностью не являются хорошими кандидатами.

Каковы негативные последствия индексации производительности?

Уже ответил: дополнительное дисковое пространство, более низкая производительность во время insert - update - delete.

Если у меня есть столбец VARCHAR 2500, доступный для поиска с частей моего сайта, я должен его индексировать?

Попробовать индекс FULLTEXT .

5
ответ дан Anax 16 August 2018 в 03:36
поделиться

Проверьте презентации, такие как Подробнее Освоение искусства индексирования .

Обновление 12/2012: я опубликовал новую презентацию: Как создавать индексы, Действительно . Я представил это в октябре 2012 года в ZendCon в Санта-Кларе, а в декабре 2012 года в Percona Live London.

Разработка лучших индексов - это процесс, который должен соответствовать запросам, которые вы запускаете в своем приложении.

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

Да, есть некоторые накладные расходы, поэтому вам не нужно создавать индексы бесполезно. Но вы должны создавать индексы, которые приносят пользу запросам, которые необходимо выполнить быстро. Накладные расходы на индекс, как правило, значительно перевешиваются его выгодой.

Для столбца, который является VARCHAR (2500), вы, вероятно, захотите использовать индекс FULLTEXT или префиксный индекс:

CREATE INDEX i ON SomeTable(longVarchar(100));

Обратите внимание, что обычный индекс не может помочь, если вы ищете слова, которые могут находиться в середине этого длинного varchar. Для этого используйте полнотекстовый индекс.

47
ответ дан Bill Karwin 16 August 2018 в 03:36
поделиться

Вы обязательно должны потратить некоторое время на чтение индексации, об этом много написано, и важно понять, что происходит.

В широком смысле, и индекс накладывает порядок на строках Таблица.

Для простоты представьте, что таблица - это просто большой CSV-файл. Всякий раз, когда строка вставлена, она вставлена ​​ в конец . Таким образом, «естественный» порядок таблицы - это просто порядок, в который были вставлены строки.

Представьте, что у вас есть файл CSV, загруженный в очень рудиментарное приложение для электронных таблиц. Вся эта таблица - это отображение данных и номера строк в последовательном порядке.

Теперь представьте, что вам нужно найти все строки с некоторым значением «M» в третьем столбце. Учитывая то, что у вас есть, у вас есть только один вариант. Вы просматриваете таблицу, проверяя значение третьего столбца для каждой строки. Если у вас много строк, этот метод («сканирование таблицы») может занять много времени!

Теперь представьте, что помимо этой таблицы у вас есть индекс. Этот конкретный индекс является индексом значений в третьем столбце. Индекс перечисляет все значения из третьего столбца, в каком-то значимом порядке (скажем, в алфавитном порядке) и для каждого из них, содержит список номеров строк, где это значение появляется.

Теперь у вас есть хороший стратегия поиска всех строк, где значение третьего столбца равно «M». Например, вы можете выполнить двоичный поиск ! В то время как сканирование таблицы требует, чтобы вы искали N строк (где N - количество строк), бинарный поиск требует только поиска записей индекса log-n в самом худшем случае. Вау, это намного проще!

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

Итак, в целом индексирование создает компромисс между эффективностью чтения и написать эффективность. Без индексов вставки могут быть очень быстрыми - механизм базы данных просто добавляет строку в таблицу. Когда вы добавляете индексы, движок должен обновлять каждый индекс во время выполнения вставки.

С другой стороны, чтение становится намного быстрее.

Надеюсь, это касается ваших первых двух вопросов (как ответили другие - вам нужно найти правильный баланс).

Ваш третий сценарий немного сложнее. Если вы используете LIKE, двигатели индексирования обычно будут поддерживать скорость чтения до первого «%». Другими словами, если вы выбрали столбец SELECT WHERE LIKE 'foo% bar%', база данных будет использовать индекс для поиска всех строк, где столбец начинается с «foo», а затем нужно сканировать этот промежуточный набор строк, чтобы найти подмножество который содержит «бар». SELECT ... WHERE column LIKE '% bar%' не может использовать индекс. Надеюсь, вы можете понять, почему.

Наконец, вам нужно начать думать об индексах более чем в одном столбце. Концепция такая же и ведет себя аналогично вещам LIKE - крайне важно, если у вас есть индекс на (a, b, c), двигатель будет продолжать использовать индекс слева направо, насколько это возможно. Таким образом, поиск в столбце a может использовать индекс (a, b, c), как и один (a, b). Однако, если вы искали WHERE b = 5 И c = 1, движок должен был бы выполнить полное сканирование таблицы.

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

203
ответ дан manoj2411 16 August 2018 в 03:36
поделиться
  • 1
    Как насчет индексов FULLTEXT? Могут ли они помочь с такими условиями, как LIKE '%bar%'? – Septagram 15 March 2013 в 10:35

1/2) Индексы ускоряют определенные операции выбора, но замедляют другие операции, такие как вставка, обновление и удаление. Это может быть прекрасный баланс.

3) используйте полный текстовый индекс или, возможно, sphinx

4
ответ дан Paul Creasey 16 August 2018 в 03:36
поделиться
  • 1
    Чтобы предотвратить slow down other operations like insert, update and deletes, вы можете использовать START TRANSACTION; YOUR CODE HERE; COMMIT, что может помочь избежать slowing down других операций, поскольку он будет проверять только один раз один раз. CAVEAT: Если вы используете REPLACE INTO и ваш SQL_MODE & gt; STRICT_ALL_TABLES ИЛИ TRADITIONAL Bulk Load будет игнорировать замену и вставить дубликаты. – JayRizzo 23 June 2017 в 16:59

Если таблица имеет шесть столбцов, и все они доступны для поиска, я должен индексировать их все или ни один из них

. Вы ищете по полю по полю или некоторые поиски с использованием нескольких полей? Какие поля находятся в в большинстве ? Каковы типы полей? (Индекс лучше работает на INT, чем на VARCHAR, например) Пробовали ли вы использовать EXPLAIN для выполняемых запросов?

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

UPDATE и INSERT будут медленнее.

Если у меня есть столбец VARCHAR 2500, который можно найти на сайтах моего сайта, я должен индексировать его

/ blockquote>

Нет, если это не UNIQUE (это означает, что оно уже проиндексировано), или вы только выполняете поиск точных совпадений в этом поле (не используя полнотекстовый поиск LIKE или mySQL).

< blockquote>

Как правило, я помещаю индекс в любые поля, которые я буду искать или выбирать с помощью предложения WHERE

. Я бы обычно индексировал поля, которые наиболее опрошены, а затем INTs / BOOLEANs / ENUM скорее поля, которые являются VARCHARS. Не забывайте, часто вам нужно создать индекс в комбинированных полях, а не индекс в отдельном поле. Используйте EXPLAIN и проверьте медленный журнал.

20
ответ дан Pete 16 August 2018 в 03:36
поделиться

Эффективность загрузки данных: индексы ускоряют поиск, но замедляют вставку и удаление, а также обновляют значения в индексированных столбцах. То есть индексы замедляют большинство операций, связанных с написанием. Это происходит потому, что для записи строки требуется запись не только строки данных, но и изменения любых индексов. Чем больше индексов имеет таблица, тем больше изменений необходимо сделать и тем больше ухудшение средней производительности. Большинство таблиц получают много чтений и несколько записей, но для таблицы с высоким процентом записей стоимость обновления индекса может быть значительной.

Избегайте индексов: если вам не нужен определенный индекс, чтобы помочь

Дисковое пространство: индекс занимает дисковое пространство, а несколько индексов занимают соответственно больше места. Это может привести к тому, что вы достигнете предела размера таблицы быстрее, чем если нет индексов. Избегайте индексов, где это возможно.

Вынос: не перегружайте индекс

10
ответ дан Srikar Doddi 16 August 2018 в 03:36
поделиться

Я не буду повторять некоторые полезные советы в других ответах, но добавлю:

Компонентные индексы

Вы можете создавать составные индексы - индекс, который включает в себя несколько столбцов. MySQL может использовать их слева направо. Поэтому, если у вас есть:

Table A
Id
Name
Category
Age
Description

, если у вас есть составной индекс, который включает в себя имя / категорию / возраст в этом порядке, эти предложения WHERE будут использовать индекс:

WHERE Name='Eric' and Category='A'

WHERE Name='Eric' and Category='A' and Age > 18

но

WHERE Category='A' and Age > 18

не будет использовать этот индекс, потому что все должно использоваться слева направо.

Объяснить

Использовать Объяснение / Объяснение Расширенного, чтобы понять, что индексы доступны для MySQL и которые он фактически выбирает. MySQL будет использовать только один ключ для каждого запроса .

EXPLAIN EXTENDED SELECT * from Table WHERE Something='ABC'

Журнал замедленного запроса

Включите журнал медленных запросов , чтобы см., какие запросы выполняются медленно.

Широкие столбцы

Если у вас есть широкий столбец, где МОСТ различий происходит в первых нескольких символах, вы можете использовать только первые N символов в ваш индекс. Пример. У нас есть столбец ReferenceNumber, определенный как varchar (255), но 97% случаев, ссылочный номер - 10 символов или меньше. Я изменил индекс, чтобы посмотреть только на первые 10 символов и улучшить производительность.

41
ответ дан winwaed 16 August 2018 в 03:36
поделиться
  • 1
    У меня вопрос о последней части. Я где-то читал, что если вы создаете столбец с VARCHAR, вы должны всегда устанавливать его на 255. Теперь вы сказали, что индекс, установленный для этого типа столбца, может ограничиваться только для первых 10 символов. Как именно вы можете это сделать? – AlexioVay 23 February 2017 в 12:31
  • 2
    Будет ли WHERE Name='Eric' and Age > 18 работать? – Mr Roshan Pawar 4 August 2017 в 10:25
Другие вопросы по тегам:

Похожие вопросы: