Индексы SQL Server - PullRequest
       8

Индексы SQL Server

0 голосов
/ 20 июля 2010

Я был пользователем MySQL.Сейчас я перехожу на SQL Server.Но у меня есть проблема.Я не могу найти какой-либо способ указать тип индекса таблицы.В MySQL я легко могу сказать, что нужно создать BTree Index или Hash Index.Как я могу сделать это здесь?

Основная проблема заключается в том, что у меня есть две таблицы.один из них (с именем «posts») имеет внешний ключ к другому (с именем «users»), который имеет ограничение первичного ключа для «id».В моей java-программе для вставки постов я должен проверить, был ли вставлен пользователь этого поста, и если нет, вставить его (сначала я не могу вставить всех пользователей!).

Этот код вставлял около1000 сообщений через каждые 10 секунд в MySQL.Но в SQL Server поисковая часть занимает слишком много времени, а 1000 сообщений занимают более 1 минуты.

Это медленный запрос SQL:

select * from users u where u.id = "UserName"

Это пользовательская таблица:

CREATE TABLE [dbo].[users](
[id] [varchar](50) NOT NULL,
[type] [char](1) NULL,
[name] [nvarchar](150) NULL,
[reserved] [char](8) NULL,
[description] [nvarchar](4000) NULL,
[text] [ntext] NULL,
 CONSTRAINT [PK__users__3213E83F00551192] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

В чем проблема?

Спасибо.

Ответы [ 4 ]

2 голосов
/ 20 июля 2010

В MySQL я легко могу сказать, что нужно создать BTree Index или Hash Index.

Индексы не являются стандартом ANSI, сходство между поставщиками баз данных удивительно для этого факта.Кроме того, MySQL и SQL Server более похожи, чем другие пары ... Хотя SQL Server не позволяет указывать индексы как BTREE или HASH, существуют другие элементы управления, которые не предоставляются MySQL .

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

select * from users u where u.id = "UserName"
  1. SELECT * допустимо только в том случае, если вы используете данные из всех возвращенных столбцов.Столбцы, содержащие большое количество текста, могут негативно повлиять на производительность запроса.В идеале, никогда не используйте SELECT * - всегда указывайте, какие столбцы используются.На SO много вопросов о производительности SELECT * и о том, как этого следует избегать.
  2. Сохранение строки в качестве значения id не будет таким быстрым, как если бы это было INT
  3. Используйте одинарные кавычки,не двойной, чтобы указать строку в SQL
1 голос
/ 20 июля 2010

Первый способ создать индекс - создать первичный ключ. Это будет иметь связанный уникальный индекс. Столбец u.id может быть кандидатом в первичный ключ, если u.id содержит уникальные значения.

Если u.id не является уникальным или вы не хотите, чтобы он был первичным ключом, вы можете создать для него индекс со следующим:

CREATE INDEX ix_users_id
ON users (id)
;

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

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

1 голос
/ 20 июля 2010

SQL Server не поддерживает хеш-индексы. Список доступных индексов можно найти здесь .

Если вы пытаетесь вставить тысячи записей в секунду, звучит так, как будто вам лучше использовать BULK INSERT . В идеале вы бы сделали это:

  • Массовая вставка всех пользователей.
  • Массовая вставка всех сообщений.

Учитывая ваше требование не вставлять всех пользователей первым, я бы предложил что-то вроде этого:

  • Снимите ограничение внешнего ключа.
  • Массовая вставка всех сообщений.
  • Запрос, чтобы найти, какие пользователи отсутствуют, и вставить их (это можно сделать одним оператором).
  • Снова добавить ограничение.
0 голосов
/ 21 июля 2010

Вы уверены, что запрос в вашем сообщении точно запрос, который вы выполняете? Может быть, вы случайно запустили select * from users u where u.id = @userName?

Чрезвычайно распространенная проблема в разработке приложений - это вставка в параметры Unicode для поиска столбцов ASCII. Это может проникнуть в код с помощью простого опечатки в типе отображения в NHibernate, или с помощью параметра, добавленного с SqlCommand.Parameters.AddWithValue("@userName", Request["userName"]); или чем-то подобным. В результате запрос выполнит сканирование вместо поиска из-за правил SQL приоритет типа данных .

Я не говорю, что это твоя проблема. Я говорю, что могут быть такие мелочи, как эта, которые могут поставить вас на неверную сторону плана запроса. К счастью, есть инструменты для устранения неполадок и расследования любой проблемы. Вот хороший старт: Устранение неполадок с производительностью в SQL Server 2005 .

В качестве примечания, индексы BTree работают невероятно быстро, вам не нужны индексы Hash;)

...