[DB] Хочу убрать задержку выполнения запроса.
При выполнении соответствующих JOIN-ов (1)Честно говоря, Delphi не знаю, но вопрос, как я понял, и не требует этого знания.
У меня вопрос к автору - какие JOIN-ы имеются ввиду? В смысле о чем речь, если в запросе нет JOIN?
К тому же не похоже, чтобы такой несложный запрос для относительно маленькой таблицы (100,000 строк) выполнялся 10 секунд. Может что-то с настройками базы? Или с индексами?
К тому же не понятно, зачем создавать вьюху. Нет никакой существенной разницы между тем, будешь ли ты получать нужную информация путем запроса или используешь select из вьюхи, которая основывается на этом запросе. При вызове SELECT my_view ... все равно будет выполнен запрос, который находится в my-view. Есть материализованные вьюхи - это другое дело. Но я не уверен, поможет ли тебе это...
У меня вопрос к автору - какие JOIN-ы имеются ввиду? В смысле о чем речь, если в запросе нет JOIN?Этот запрос эквивалентен
SELECT ...
FROM Games INNER JOIN Players AS A ON FirstID=A.PlayerID INNER JOIN Players AS B ON SecondID = B.PlayerID
WHERE CustomCondition
Поэтому я и написал для удобства JOIN.
Да, и запрос исполняется не над 100 000 табличкой Games, а над Games*Players*Players. Я понимаю, что это оптимизируется, но не до 100 000 все равно.
А какой размер PLAYERS?
Слуш, а глянь-ка план выполнения запроса.
Когда-то видел такой косяк, типа бд-сервак составил план выполнения запроса для десятка записей и закешировал, на миллионе записей тормозило ессно.
100000 - небольшая цифра.
Что за сервер кстати?
Когда-то видел такой косяк, типа бд-сервак составил план выполнения запроса для десятка записей и закешировал, на миллионе записей тормозило ессно.
100000 - небольшая цифра.
Что за сервер кстати?
SELECT ...А чем INNER JOIN отличается от серии AND-ов?
FROM Games INNER JOIN Players AS A ON FirstID=A.PlayerID INNER JOIN Players AS B ON SecondID = B.PlayerID
WHERE CustomCondition
Чем этот запрос лучше/хуже того, что приведено в исходном вопросе?
Сервер - NexusDB, не очень-то он знаменит, зато коряв 
Настолько коряв, что план вып-я запроса не кеширует. Ну и неважно, впрочем, я сразу создал базу из 100к записей, а потом только начал слать запросы.
Почему-то у меня стойкое подозрение, что улучшить время выполнения ЭТОГО запроса не получится, по крайней мре в рамках Нексуса.
З.Ы. Таблица Games на диске весит 120 Мб, ибо там BLOB-ы. Но и при SELECT-е без блобов выполнение запроса хоть и ускоряется, но до 5 секунд, что все равно много.
А 100 000 - это для теста. Желательно, чтобы не тормозило на 3 миллионах записей.

Настолько коряв, что план вып-я запроса не кеширует. Ну и неважно, впрочем, я сразу создал базу из 100к записей, а потом только начал слать запросы.
Почему-то у меня стойкое подозрение, что улучшить время выполнения ЭТОГО запроса не получится, по крайней мре в рамках Нексуса.
З.Ы. Таблица Games на диске весит 120 Мб, ибо там BLOB-ы. Но и при SELECT-е без блобов выполнение запроса хоть и ускоряется, но до 5 секунд, что все равно много.
А 100 000 - это для теста. Желательно, чтобы не тормозило на 3 миллионах записей.
Нереальная жесть.
Поставь... ну хоть MySQL, уже проблем не будет.
Если со сменой движка БД проблемы - кажися дальше только денормализация.
Поставь... ну хоть MySQL, уже проблем не будет.
Если со сменой движка БД проблемы - кажися дальше только денормализация.
С точки зрения логики - ничем не отличается, т.к. результат тот же.
С точки зрения НОРМАЛЬНОГО оптимизатора запросов - тоже ничем, т.к. он должен понимать, что это одно и то же.
Мой сервер, кстати, перед выполнением запроса с INNER JOIN-ами превращает их в WHERE ... AND ..., т.е. в первый вариант.
С точки зрения НОРМАЛЬНОГО оптимизатора запросов - тоже ничем, т.к. он должен понимать, что это одно и то же.
Мой сервер, кстати, перед выполнением запроса с INNER JOIN-ами превращает их в WHERE ... AND ..., т.е. в первый вариант.
А клиентскую часть модифицировать не стоит? В первом посте написан огрызок соответствующей идеи... Ведь результат запроса нужен именно юзеру, и нужен не сразу весь, а по частям, чтобы на него глядеть.
Завтра буду пробовать на другом БД-движке, но штука в том, что они, гады, платные
А нужно не абы какой, а чтобы встраивался в exe-шник.
Завтра буду пробовать на другом БД-движке, но штука в том, что они, гады, платные
А нужно не абы какой, а чтобы встраивался в exe-шник.такой запрос за сколько делается?
SELECT GameID, FirstId, SecondId, Score, Date, ...
FROM Games
where <custom condition>
Завтра буду пробовать на другом БД-движке, но штука в том, что они, гады, платныеOracle - бесплатный
3 секунды, зараза такая, он делается.
Но именно с Nexus-ом можно расчеты над ОДНОЙ таблицей перенести на клиента (т. наз. Live Request). Я с ним мало экспериментировал, но похоже, что он как раз "размазывает" эти три секунды по времени, пока юзер давит кнопку вниз
Но в случае JOIN-а ничего не катит. Сначала сервер все равно делает JOIN, на что тратит основное время.
P.S. ушел часа на два.
Но именно с Nexus-ом можно расчеты над ОДНОЙ таблицей перенести на клиента (т. наз. Live Request). Я с ним мало экспериментировал, но похоже, что он как раз "размазывает" эти три секунды по времени, пока юзер давит кнопку вниз

Но в случае JOIN-а ничего не катит. Сначала сервер все равно делает JOIN, на что тратит основное время.
P.S. ушел часа на два.
результат запроса нужен именно юзеру, и нужен не сразу весь, а по частямХм, я наверное не слишком правильно понял...
По логике работы приложения ты можешь сделать разбиение на страницы? если да - то вытаскиваешь общее количество записей (кстати, посмотри время выполнения) и делишь на кол-во записей на "страницу".
Или ты хочешь все равно подгрузить все записи, но как бы частями?
Я смотрел уже - общее количество записей считается тоже секунды за 2. Да и не очень понятно, как загрузить, скажем, "записи с 10000 по 11000 из такого-то запроса" Есть, конечно
SELECT ... WHERE ... LIMIT 10000,1000
, но а) эта конструкция не поддерживается столь любимым Нексусом, б) подозреваю, что все равно запрос выполняется целиком.
SELECT ... WHERE ... LIMIT 10000,1000
, но а) эта конструкция не поддерживается столь любимым Нексусом, б) подозреваю, что все равно запрос выполняется целиком.
ты б хоть указал на то, какие в таблицах поля и какие у них ключи. А то это всё какие-то теоретизирования...
По делу - у тебя или по какой-то причине ключи не работают, или БД жутко тупая.
По делу - у тебя или по какой-то причине ключи не работают, или БД жутко тупая.
Оставить комментарий
zorin29
Дано: БД с 2 таблицами: Games, Players.Players: PlayerID, Name, Country, ...
Games: GameID, FirstID, SecondID, Score, Date, ...
Юзер как правило (95%) просматривает результат следующего запроса
SELECT GameID, A.Name as First, B.Name as Second, Score, Date, ...
FROM Games, Players as A, Players as B
WHERE A.PlayerID = FirstID AND B.PlayerID = SecondID AND <custom condition>, в частности часто custom condition-а вовсе нет.
1) Query.Open;
2) DBGrid.DataSource.DataSet := Query;
При выполнении соответствующих JOIN-ов (1) SQL-сервер тормозит секунд 10 (|Games| = 100 000, индексы построены). Затем юзер просматривает результат без торможений, подкачивая при необходимости данные.
Мне не нравится торможение в 10 секунд. Как бы его убрать, т.е. "размазать" во времени?
Я надумал вариант с расслоением Games:
SELECT ... FROM ... WHERE ... AND (GameID BETWEEN 10000 AND 12000)
Такие запросы выполняются мнговенно. Но в результате из-за Custom Condition в полученном DataSet-е может оказаться слишком мало записей... Как быть?
В принципе, можно пробовать сменить архитектуру базы, сменить SQL-engine, перестать использовать SQL и т.д. - свобода довольно большая.
Решение
CREATE VIEW GamesPlayers AS
SELECT GameID, A.Name as First, B.Name as Second, Score, Date, ...
FROM Games, Players as A, Players as B
WHERE A.PlayerID = FirstID AND B.PlayerID = SecondID
SELECT * FROM GamesPlayers WHERE CustomCondition
не работает, т.к. VIEW в случае нашего SQL-сервера создается только в момент SELECT, а потом удаляется - ускорения не получаем.