Поле, на котором выполняется этот запрос, - это выделенный сервер, работающий в центре данных.
AMD Opteron 1354 Quad-Core 2,20 ГГц
2 ГБ ОЗУ
Windows Server 2008 x64 (Да, я знаю, что у меня только 2 ГБ ОЗУ, я обновляю до 8 ГБ, когда проект будет запущен).
Итак, я прошел и создал 250 000 фиктивных строк в таблице, чтобы провести стресс-тестирование некоторых запросов, которые генерирует LINQ to SQL, и убедиться, что они не ужасные, и я заметил, что один из них занимал абсурдное количество времени. 1005 *
У меня был этот запрос до 17 секунд с индексами, но я удалил их ради этого ответа, чтобы переходить от начала к концу. Только индексы являются первичными ключами.
Stories table --
[ID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [int] NOT NULL,
[CategoryID] [int] NOT NULL,
[VoteCount] [int] NOT NULL,
[CommentCount] [int] NOT NULL,
[Title] [nvarchar](96) NOT NULL,
[Description] [nvarchar](1024) NOT NULL,
[CreatedAt] [datetime] NOT NULL,
[UniqueName] [nvarchar](96) NOT NULL,
[Url] [nvarchar](512) NOT NULL,
[LastActivityAt] [datetime] NOT NULL,
Categories table --
[ID] [int] IDENTITY(1,1) NOT NULL,
[ShortName] [nvarchar](8) NOT NULL,
[Name] [nvarchar](64) NOT NULL,
Users table --
[ID] [int] IDENTITY(1,1) NOT NULL,
[Username] [nvarchar](32) NOT NULL,
[Password] [nvarchar](64) NOT NULL,
[Email] [nvarchar](320) NOT NULL,
[CreatedAt] [datetime] NOT NULL,
[LastActivityAt] [datetime] NOT NULL,
В настоящее время в базе данных есть 1 пользователь, 1 категория и 250 000 историй, и я попытался выполнить этот запрос.
SELECT TOP(10) *
FROM Stories
INNER JOIN Categories ON Categories.ID = Stories.CategoryID
INNER JOIN Users ON Users.ID = Stories.UserID
ORDER BY Stories.LastActivityAt
Выполнение запроса занимает 52 секунды, загрузка ЦП колеблется на 2-3%, Membery составляет 1,1 ГБ, свободно 900 МБ, но использование диска кажется неуправляемым. Это @ 100 МБ / с, из которых 2/3 записывается в tempdb.mdf, а остальное - из tempdb.mdf.
Теперь по интересной части ...
SELECT TOP(10) *
FROM Stories
INNER JOIN Categories ON Categories.ID = Stories.CategoryID
INNER JOIN Users ON Users.ID = Stories.UserID
SELECT TOP(10) *
FROM Stories
INNER JOIN Users ON Users.ID = Stories.UserID
ORDER BY Stories.LastActivityAt
SELECT TOP(10) *
FROM Stories
INNER JOIN Categories ON Categories.ID = Stories.CategoryID
ORDER BY Stories.LastActivityAt
Все 3 из этих запросов в значительной степени мгновенные.
План выполнения первого запроса.
http://i43.tinypic.com/xp6gi1.png
Планы Exec для других 3 запросов (по порядку).
http://i43.tinypic.com/30124bp.png
http://i44.tinypic.com/13yjml1.png
http://i43.tinypic.com/33ue7fb.png
Любая помощь будет принята с благодарностью.
План Exec после добавления индексов (снова до 17 секунд).
http://i39.tinypic.com/2008ytx.png
Я получил много полезных отзывов от всех, и я благодарю вас, я попытался по-новому взглянуть на это. Я запрашиваю истории, которые мне нужны, затем в отдельных запросах получаем Категории и пользователей, и с 3 запросами это заняло всего 250 мс ... Я не понимаю проблему, но если она будет работать и на 250 мс не меньше, я пока придерживаться этого. Вот код, который я использовал для проверки этого.
DBDataContext db = new DBDataContext();
Console.ReadLine();
Stopwatch sw = Stopwatch.StartNew();
var stories = db.Stories.OrderBy(s => s.LastActivityAt).Take(10).ToList();
var storyIDs = stories.Select(c => c.ID);
var categories = db.Categories.Where(c => storyIDs.Contains(c.ID)).ToList();
var users = db.Users.Where(u => storyIDs.Contains(u.ID)).ToList();
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);