Составной индекс, требуемый ускорять запрос, к которому присоединяются?

Коллега попросил, чтобы я объяснил как индексы (индексы?) повышают производительность; я попытался сделать так, но запутался сам.
Я использовал модель ниже для объяснения (ошибка/диагностика при входе базы данных). Это состоит из трех таблиц:

  • Список бизнес-систем, таблица "System", содержащая их имена
  • Список различных типов трассировок, таблицы "TraceTypes", определяя, какие виды сообщений об ошибках могут быть зарегистрированы
  • Фактические сообщения трассировки, имея внешние ключи от System и TraceTypes таблицы

Я использовал MySQL для демонстрации, однако я не вспоминаю типы таблицы, которые я использовал. Я думаю, что это был InnoDB.

 System                                TraceTypes
-----------------------------         ------------------------------------------
| ID          | Name        |         | ID    | Code   | Description           |
-----------------------------         ------------------------------------------
| 1           | billing     |         | 1     | Info   | Informational mesage  |
| 2           | hr          |         | 2     | Warning| Warning only          |
-----------------------------         | 3     | Error  | Failure               |
           |                          ------------------------------------------
           |                ------------|
 Traces    |                |            
 --------------------------------------------------
 | ID | System_ID | TraceTypes_ID | Message       |
 --------------------------------------------------
 | 1  |  1        |  1            | Job starting  |
 | 2  |  1        |  3            | System.nullr..|
 --------------------------------------------------

Во-первых, я добавил некоторые записи на все таблицы и продемонстрировал, что запрос ниже выполняется за 0,005 секунды:

select count(*) from Traces 
  inner join System on Traces.System_ID = System.ID
  inner join TraceTypes on Traces.TraceTypes_ID = TraceTypes.ID
where 
  System.Name='billing' and TraceTypes.Code = 'Info'

Затем я генерировал больше данных (никакие индексы все же)

  • "Система" содержала приблизительно 100 записей
  • "TraceTypes" содержал приблизительно 50 записей
  • "Трассировки" содержали ~10 миллионов записей.

Теперь предыдущий запрос занял 8-10 секунд.

Я создал индексы на Traces.System_ID столбец и Traces.TraceTypes_ID столбец. Теперь этот запрос, выполняемый в миллисекундах:

select count(*) from Traces where System_id=1 and TraceTypes_ID=1;

Это было также быстро:

select count(*) from Traces 
  inner join System on Traces.System_ID = System.ID
where System.Name='billing' and TraceTypes_ID=1;

но предыдущий запрос, который присоединился ко всем этим трем таблицам все еще, занял 8-10 секунд для завершения.

Только, когда я создал составной индекс (оба столбца System_ID и TraceTypes_ID, включенные в индекс), скорость снизилась до миллисекунд.

Основное утверждение, которое мне преподавали ранее, является "всеми столбцами, которые Вы используете для присоединения, должен быть индексирован".
Однако в моем сценарии у меня были индексы на обоих System_ID и TraceTypes_ID, однако MySQL не использовал их. Вопрос - почему? Мои ставки - отношение количества объекта 100:10,000,000:50 делает индексы отдельного столбца слишком большими, чтобы использоваться. Но действительно ли это верно?

6
задан naivists 12 January 2010 в 09:09
поделиться

3 ответа

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

Вот пример (необходимо скомпилировать и запустить; 2.7 REPL, по крайней мере, не нравится многострочный XML в операторах случаев).

object Test {

import scala.xml._

def whiten(xml: Node,w:String): Node = {
  val bits = Node.unapplySeq(xml)
  val white = new Text(w)
  val ab = new scala.collection.mutable.ArrayBuffer[Node]()
  ab += white;
  bits.get._3.foreach {b => ab += b ; ab += white }
  new Elem(
    xml.prefix,
    xml.label,
    xml.attributes,
    xml.scope,
    ab: _*
  );
}

val xml = <a><b>123</b><c>Works</c></a>

def main(args:Array[String]) {
  whiten(xml,"""
         """  // You must match the multiline whitespace to your case indentation!
  ) match { 
    case <a>
         <b>123</b>
         <c>{x}</c>
         </a> => println(x)
    case _ => println("Fails")
  }
}

}

Довольно неуместно, но это (незначительно) достигает того, что вы хотите.

-121--4407699-

Silverlight является подмножеством WPF, primariliy Silverlight ориентирована на анимацию и медиа, на самом деле не предназначена для выполнения сложных и больших приложений Desktop, Вы, конечно, могли бы, но не на его основное назначение.

WPF может размещаться на веб-странице и имеет кросс-поддержку браузера (IE и Firefox)

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

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

-121--3165688-

Во-первых, правильный и самый простой способ анализа медленной инструкции SQL - это выполнить команду ПОЯСНИТЬ. Узнайте, как оптимизатор выбрал свой план, и подумайте, почему и как это улучшить. Я бы предложил изучить результаты ОБЪЯСНЕНИЯ только с 2 отдельными индексами, чтобы увидеть, как mysql выполнить ваш оператор.

Я не очень хорошо знаком с MySQL, но кажется, что существует ограничение MySQL 4 использовать только один индекс на таблицу, участвующую в запросе. Похоже, в этом есть улучшения, поскольку MySQL 5 ( слияние индекса ), но я не уверен, применим ли он к вашему делу. Опять же, ОБЪЯСНИ должен сказать тебе правду.

Даже при использовании 2 индексов на таблицу (MySQL 5) использование 2 отдельных индексов, как правило, медленнее, чем составного индекса. Использование 2 отдельных индексов требует шага объединения индексов по сравнению с одним шагом использования составного индекса.

Использование MySQL 5.4.2 может оказаться полезным в сравнении с объединением индексов .

2
ответ дан 17 December 2019 в 18:16
поделиться
  • Перегрузка методов - это хитрость компилятора, позволяющая использовать одно и то же имя для выполнения различных действий в зависимости от параметров.

  • Переопределение метода означает, что заменяется вся его функциональность. Переопределение выполняется в дочернем классе для метода, определенного в родительском классе.

src: http://www.jchq.net/tutorial/06_02Tut.htm

-121--3033949-

Я предполагаю, что он будет использовать индекс, а затем он может использовать традиционный поиск для перемещения к другому индексу, а затем отфильтровывать. Проверьте план выполнения. Короче говоря, вы можете закольцовывать два индекса во вложенном цикле. Согласно моему пониманию. Мы должны попытаться создать составной индекс для столбца, который находится в фильтрации или в соединении, а затем мы должны использовать предложение Include для столбцов, которые находятся в выборке. Я никогда не работал в MySql, поэтому мое понимание основано на SQL Server 2005.

-121--4482099-

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

1
ответ дан 17 December 2019 в 18:16
поделиться

Я предполагаю, что он будет использовать индекс, а затем, возможно, будет использовать традиционный поиск вверх, чтобы перейти к другому индексу, а затем отфильтровать. Пожалуйста, проверьте план выполнения. Короче говоря, вы можете перебирать два индекса во вложенном цикле. Как я понимаю. Мы должны попытаться сделать составной индекс по столбцам, которые находятся в фильтрации или в соединении, а затем мы должны использовать пункт Include для столбцов, которые находятся в селекции. Я никогда не работал в MySql, поэтому мое понимание основано на SQL Server 2005.

0
ответ дан 17 December 2019 в 18:16
поделиться
Другие вопросы по тегам:

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