Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
alexeyvg
Questq2
А точно никак нельзя побороть вычисляемое поле?
Нет, нельзя. Вот если бы вы не использовали формат AM/PM...


Да нет у меня формата 12-часового. В БД смотрю и вижу только 24-часовой. Эта формула (CONVERT([time](0),[времяизвнешнегоПО],0)) - пишет 24-часовой формат.

alexeyvg
Конечно неоптимально, вот я и предлагаю хранить сразу в 2-х вариантах. У вас то сейчас пересчёты при любом селекте делаются, ну и индекс до кучи сделать нельзя. А это совсем плохо.


Что-то я запутался. Моя цель - при запросах к БД использовать формать time, и чтобы все быстро работало.

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

Таким образом, если вычисляемое поле не побороть, то остается только вариант делать вместо него обычное поле и триггером на добавление вставлять туда значение времени в формате time?
2 июл 11, 16:25    [10911609]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8877
Извините, шо я врываюсь тута...
В общем, если на интересующей таблице есть поле timestamp (не путуть с возвращаемым значением current_timestamp),
то я бы селектил в приложении @@DBTS и следил за ейным изменением. Поменялось что-то - перечитать. Не поменялось - ничего не трогать.

По топику: в своё время я наговнокодил на сишарпе утилитку - она живёт в трее и раз в сколько-то секунд шлёт запрос в базу (считается количество записей по условию) - если > 0 , выставляет флаговую переменную. Если 0, то сбрасывает её. Асинхронно по второму таймеру в трее отображается та или иная иконка.

В топике мне понравилась идея и как вариант - повесить триггер и апдейтить флаг в маленькой (другой) таблице (или дату последней модификации). Приложение может либо в транзакци во время проверки сбрасывать флаг либо делать проверку. А ворошить каждым запросом таблицу на предмет max(Дата) или условия where Дата > КонтрольнаяДата...; по-моему это только сервак напрягать... Хотя если есть индивидуальный индекс по Дата, то max(Дата) будет работать шустро.
ИМБО.
Удачи!
2 июл 11, 17:01    [10911638]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
Questq2
Да нет у меня формата 12-часового. В БД смотрю и вижу только 24-часовой.
Не понял, а зачем ваы тогда используете формат №0, который нужен только для представления времени в 12-ти яасовом формате???

Выберите для формулы правильное число в CONVERT и спокойно делайте индекс. Не для всех стилей преобразования сиквел будет ругаться.

Questq2
Эта формула (CONVERT([time](0),[времяизвнешнегоПО],0)) - пишет 24-часовой формат.
Эта формула не может писать 24-часовой формат, она же возвращает тип время, у которого не бывает форматов. Это 4-х байтное число, какой у него формат?

Формута читает строку, и переводит текст в ней из 12-ти часового строкового представления времени в тип время. При этом сайбейс так реализовал функцию CONVERT, что она не возвращает ошибки, если ей подсунуть 24-х часовой формат

Т.е., вы используете типичный для программистов принцип - я написал, а оно и заработало :-) Несколько ошибок компенсировали друг друга.
3 июл 11, 17:36    [10914028]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
alexeyvg, спасибо, разобрался со стилями, нашел детерминированное представление.

Вот такой еще вопрос возник:

1. Если я объединю экспортируемые внешним приложением поля Дата (в текстовом формате) и Время (в текстовом формате) в одном вычисляемом поле БД с типом datetime, это будет более оптимальный вариант с точки зрения скорости запросов? То есть, индекс будет всего по двум полям: Код и это вычислемое поле с типом datetime.

2. Мне надо получить в вычисляемом поле на выходе дату и время без миллисекунд, то есть тип данных smalldatetime. Но как сделать такое вычисляемое поле из двух других полей? Я пробую так:

[ДатаВремя] AS (CAST ([ИзВнешнегоПОДата] +' '+ [ИзВнешнегоПОВремя] AS smalldatetime)),

Студия не ругается, но при запуске заполнения из внешнего ПО - все виснет. Где неправильно?
3 июл 11, 20:10    [10914394]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
Со вторым вопросом разобрался, осталься только первый - будет ли быстрее или медленнее, если дата и время будут хранититься в типе datetime?
3 июл 11, 22:47    [10915026]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
И еще дурацкий вопрос: вычисляемые поля вычисляются сразу при добавлении записей в таблицу и хранятся в ней, или они вычисляются в момент запроса?
3 июл 11, 22:50    [10915045]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8877
Questq2
Вот такой еще вопрос возник:
1. Если я объединю экспортируемые внешним приложением поля Дата (в текстовом формате) и Время (в текстовом формате) в одном вычисляемом поле БД с типом datetime, это будет более оптимальный вариант с точки зрения скорости запросов? То есть, индекс будет всего по двум полям: Код и это вычислемое поле с типом datetime.

Ну раз уж пошла такая пьянка... - а не проще ли вам сразу с клиентского приложения в базу писать данные в поле datetime (коли вы начали ратовать за скорость)?
4 июл 11, 00:11    [10915529]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
SIMPLicity_, там более сложная схема. Заполняет БД стороннее приложение, которое выводит данные только в строковых форматах. Тут я никак не могу повлиять ни на форматы, ни на скорость. А мое приложение уже потом работает с данными этой БД.
4 июл 11, 00:45    [10915703]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
Questq2
Со вторым вопросом разобрался
Лучьше использовать CONVERT с правильным стилем, а не CAST
Questq2
будет ли быстрее или медленнее, если дата и время будут хранититься в типе datetime?
Ну, индекс и поиск ИМХО по одному полю быстрее, чем по двум.
Questq2
И еще дурацкий вопрос: вычисляемые поля вычисляются сразу при добавлении записей в таблицу и хранятся в ней, или они вычисляются в момент запроса?
В момент запроса; в БД хранится только формула.

Однако если писать свойство PERSISTED, то вычмсляемые поля будут вычисляться в момент изменения и сохраняться в таблице, вот поэтому и будет возможно использование индексов и ускорение.
4 июл 11, 09:47    [10916447]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
alexeyvg,

ааа, так я еще помимо подбора стиля, который сделает данные детерминированными, должен еще обязательно поставить PERSISTED для этого вычисляемого поля?

Я еще раз уточню - у меня русская студия, там в спецификации (свойствах) вычисляемого поля два свойства:
1. Формула (вписывать формулу)
2. Материализованный (да/нет) - это и имеется в виду PERSISTED?
4 июл 11, 10:41    [10916809]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
А все, увидел в коде, да это он.

alexeyvg, большое спасибо за помощь!
4 июл 11, 10:46    [10916842]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
Questq2
ааа, так я еще помимо подбора стиля, который сделает данные детерминированными, должен еще обязательно поставить PERSISTED для этого вычисляемого поля?
Да, чтобы в индек его включить.
Questq2
Материализованный (да/нет) - это и имеется в виду PERSISTED?
Ага, наверное. Я то не пользовался русифицированной SSMS ...
4 июл 11, 13:33    [10918058]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
DirksDR
Member

Откуда: Пермь
Сообщений: 340
При условии "по каждому коду добавляется примерно 30 тысяч записей ", т.е. если нет обновлений (update), то для проверки на новые записи можно использовать поле ASC.
В программе мы запоминаем максимальный ASC прочитанных записей
set @lastread=ASC
потом
select @maxasc=max(ASC) from ....
и
if @lastread<@maxasc ....выполняем запрос2.
Проверка должна быстро работать, раз ASC первичный ключ и есть индекс.
4 июл 11, 14:22    [10918483]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
1. alexeyvg, индексация вроде работает, если даже поле не PERSISTED. Требуется только детерменированность.

2. DirksDR, не совсем понял смысл. Если делать запрос по полю, являющемуся первичным ключем, то будет быстрее, чем если делать запрос это индексу из двух полей? У меня сделан индекс по Код+ДатаВремя, по ним все запросы и делаются: это сочетание не уникально, но в запросах не требуется делать дальнейших ограничений условий, то есть запрашивается запись с определенным Кодом и максимальным ДатаВремя, больше определенного ДатаВремя (последнее условие сделано, чтобы отделять прошлые дни, у который будет большее время, чем в текущем дне). Или (при втором запросе), запрашиваются записи с определенным Кодом, входящие в некоторый ДатаВремя диапазон. Протестировать и сравнить скорость пока не могу, так как возникла другая проблема.

Если да, то нужно-ли создавать еще один индекс, на базе только поля первичного ключа (Номер)?

3. А новая проблема такая, что БД теперь поле с типом datetime, все заполняется и индексируется, но теперь не работают запросы из .Net к этому полю. Я пока не понял точно почему. Может, форматы datetime у .Net и SQL различаются?

То есть, к примеру, создаю переменную в своем приложении .Net:

DateTime _currentDateTime = new DateTime(2011, 07, 04, 14, 00, 00);

Засовываю эту переменную в LINQ запрос:

...
where p.ДатаВремя > _currentDateTime
...

Который преобразуется в SQL-запрос:

...WHERE (([t0].[ДатаВремя]) > @p0)...

Но итог - нет данных, хотя в реальности они есть. При этом, если сделать запрос из студии, типа такого:

	set @homeDateTime = '2011.07.04 11:40:04'
	set @endDateTime = '2011.07.04 11:45:34'
	set @Code = 'qwe'

SELECT *
FROM [All].dbo.All
WHERE
(
    (Код = @Code)
    AND
	(ДатаВремя BETWEEN @homeDateTime AND @endDateTime)
)
ORDER BY ДатаВремя, Номер

, то все ок.
4 июл 11, 16:27    [10919499]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
По третьему вопросу причина найдена - вычисляемое поле вместо 4 июня пишет дату 7 апреля, то есть месяц и день наоборот, потому запрос ничего и не возвращал.
4 июл 11, 18:48    [10920460]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
DirksDR
Member

Откуда: Пермь
Сообщений: 340
По первичному ключу индекс строится автоматически, дополнительно делать индекс по ASC не надо.
Будет ли быстрее? Может самую чуточку, в обоих случаях обращения болжны быть только к индексу.
Но лучше потестировать, т.к. индекс по дате кластерный, данные хранятся в нем, и чем черт не шутит .

Никогда не работал с LINQ, он передает серверу динамический SQL, или позволяет один раз откомпилировать запрос (Prepare у объекта Command ADO), и много раз выполнить с разными параметрами?
Если запрос каждый раз компилируется, то это будет тормозить запрос и грузить процессор.
5 июл 11, 16:05    [10926115]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
Questq2
alexeyvg, индексация вроде работает, если даже поле не PERSISTED. Требуется только детерменированность.
Да? Странно...

Действительно можно...
5 июл 11, 16:50    [10926557]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
Оказалось, дикую загрузку ЦП давало не столько отсутствие индексов, сколько вообще само наличие этого запроса:

SELECT MAX([t0].[ДатаВремя]) AS [value]
FROM [dbo].[All] AS [t0]
WHERE ([t0].[ДатаВремя] > @p0) AND ([t0].[Код] = @p1)

Что в нем такого ужасного? Монитор активности студии показывал его время выполнения 30 мс, количество выполнений - 15 в секунду. Мое внимание привлекла цифра в 7-10 000 в графе "Число логических операций чтения в секунду"

Если его просто убрать и делать запросы с ТАКОЙ ЖЕ частотой, но делать сразу "рабочий" запрос, то вся загрузка ЦП исчезает.
5 июл 11, 18:52    [10927516]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Questq2
Оказалось, дикую загрузку ЦП давало не столько отсутствие индексов, сколько вообще само наличие этого запроса:

SELECT MAX([t0].[ДатаВремя]) AS [value]
FROM [dbo].[All] AS [t0]
WHERE ([t0].[ДатаВремя] > @p0) AND ([t0].[Код] = @p1)


то есть, сейчас есть индекс не только по [t0].[ДатаВремя], но и по [t0].[Код]? покажите
5 июл 11, 19:18    [10927644]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
покажите план, имелось в виду
5 июл 11, 19:26    [10927663]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
Shakill, можно подробнее, я не вкурил...

И до, и после, у меня был один индекс по двум полям: ДатаВремя и Код. Имеете ввиду, что для приведенного запроса надо было создавать отдельный индекс?
5 июл 11, 19:44    [10927712]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Questq2, нет, я имею в виду, что по каким-то причинам индекс может не использоваться, это можно увидеть в плане выполнения

получить его можно так https://www.sql.ru/faq/faq_topic.aspx?fid=393
5 июл 11, 20:36    [10927921]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
промокатор
Guest
Questq2
Требуется, чтобы при приходе новых записей в БД, БД уведомляла второе приложение.
Continuous Query Notification (CQN) allows an application to register queries with the database for either object change notification (the default) or query result change notification. An object referenced by a registered query is a registered object.

If a query is registered for object change notification (OCN), the database notifies the application whenever a transaction changes an object that the query references and commits, regardless of whether the query result changed.

If a query is registered for query result change notification (QRCN), the database notifies the application whenever a transaction changes the result of the query and commits.
5 июл 11, 20:59    [10927979]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
Shakill, текстовый план наверно не нужен, а действительный план выполнения там куча полей, я не знаю как его сюда вставить, но я скопировал и сохранил его в файл, вот прямая ссылка http://files.mail.ru/FVOS6P только там надо немного подождать для скачки
5 июл 11, 21:16    [10928010]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше из посторонненго приложения узнать, что БД получила новые записи в таблицы?  [new]
Questq2
Member

Откуда:
Сообщений: 56
промокатор, это вроде не про MS SQL
5 июл 11, 21:20    [10928017]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить