Hariharan Arunachalam Ответов: 3

Наблюдение за таблицей MySQL в VB.net


Я разрабатываю целую кучу приложений (которые работают в сети) и подключаюсь к общей базе данных MySQL.
Из этих приложений большинство из них включают в себя ожидание, пока стол будет готов.
1. Есть новая строка
2. Измените поле
3. Извлечение строк по условию поля
Моим первым побуждением было создать поток, используя систему.Нарезание резьбы.Нить(Адрес X)
а затем имейте в то время как истинный цикл внутри, который продолжает запрашивать таблицу, а затем спит в течение небольшого количества времени (около 250-1000 МС)
Проблема в том, что приложения вызывают скачок загрузки процессора моей системы до 100% (имейте в виду, я использую четырехъядерный процессор, 4 ГБ оперативной памяти) и использование памяти тоже достигает 100%!
Обычно не имеет значения, сколько приложений запущено из системы.
Поэтому я подумал, что, возможно, резьба-это не ответ. Это из-за постоянных запросов?
Может ли кто-нибудь опытный в наблюдении за БД, пожалуйста, помочь мне?
У меня уже есть потоковые приложения. Большинство из них таковы:

1. MainUI.frm будет иметь класс
TableWatcherX

2.
TableWatcherX
будет иметь метод Start() и a
private workingThread as Thread

3. в методе Start() я ставлю
workingThread = new Thread(AddressOf KeepWorking)
                   workingThread.Start()

4. В методе KeepWorking()
While True
    Using ATable as <datasettable> = <datasetadapter>.getData
          For each of the rows, process and do stuff...
    End Using
End While</datasetadapter></datasettable>


Очевидно, что-то не так, так как моя память и процессор полностью заблокированы!
Есть какие-нибудь мысли?

3 Ответов

Рейтинг:
0

#realJSOP

Напишите хранимую процедуру, которая проверяет базу данных. Хранимая процедура должна возвращать "true", если обнаруживаются желаемые изменения.

Измените свой цикл while на этот:

Dim hasData as Boolean
Dim cmd as SqlCommand = new SqlCommand()
' setup your SqlCommand object to connect to your db and call the stored proc

while True
    hasData = CTyle(cmd.ExecutreScalar(), Boolean)
    if (hasData) Then
        'query the database (using a stored procedure again)
        'process ythe returned data
    End If
    Thread.Sleep(5000) 'sleep for 5 seconds
End While

Кроме того, поместите блок try/catch вокруг этого кода и обработайте его. ThreadAbortException. Это нормально, чтобы съесть исключение, потому что поток прерывается, когда вы вызываете Thread.Abort метод.


Hariharan Arunachalam

Поначалу я тоже обдумывал это решение. Но когда он включается, новые строки добавляются примерно каждые 3-7 секунд. Поэтому почти каждый раз я знаю, что есть данные, которые нужно извлечь. Это та часть, которая является проблемой.
Я тоже попробую это сделать.
Спасибо!

Рейтинг:
0

Dave Kreskowiak

Ваше решение ни в малейшей степени не масштабируется. Чем больше растет контролируемая таблица, тем хуже становится ваша проблема. Поскольку ваш код извлекает всю таблицу, чтобы увидеть, изменилось ли что-нибудь, каждые пару секунд, неудивительно, что ваш код привязывает процессор.

Поскольку вы используете MySQL, у вас нет доступа к каким-либо службам уведомлений, как это было бы на SQL Server. Как сказал Джон, вам придется изучить использование хранимых процедур для хранения некоторой информации, которую каждый клиент может использовать для обнаружения новых добавляемых или изменяемых строк. Одним из способов было бы присвоение серийных номеров с отметкой времени каждой строке в отслеживаемой таблице. Затем вашей хранимой процедуре может быть предоставлен последний серийный номер, который клиент видел в orde, чтобы получить только те записи, которые были изменены или обновлены.

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


Hariharan Arunachalam

Спасибо тебе, Дэйв, за то, что объяснил одну из вещей, которые я искал.
Кстати, я не извлекаю всю таблицу целиком. Существует поле состояния, которое устанавливается в поле, когда его получает первый клиент. (Поскольку многие клиенты выполняют различные уровни обработки в строке). Следующий клиент должен ждать, пока предыдущий клиент не поднимет флаг состояния до своего уровня (XSD-запрос - > SELECT * FROM Table WHERE Status = 2).
Теперь у меня есть опасения, что это может быть связано с тем, что большинство запросов используют SELECT *. Будет ли это иметь значение, если я использую каждое имя поля? В большинстве случаев мне нужны все колонки. Есть ли проблема производительности между ними обоими?

Dave Kreskowiak

SELECT * возвращает всю строку, независимо от того, сколько в ней столбцов. Указание всех имен столбцов в запросе SELECT не имеет никакого значения с точки зрения производительности.

Если вы измените схему базы данных и ваш код использует числовые индексы, чтобы получить данные в определенных столбцах вместо строк, это может вас испортить. Если порядок столбцов изменится, индексные номера в коде больше не будут указывать на те же столбцы, что и до изменения.

Hariharan Arunachalam

Еще раз спасибо, Дэйв.
Я бессонно пытался найти альтернативную базу данных для использования. Подумываю об использовании IMDB. Но не могу найти ни одного, который мог бы работать и интегрироваться с .Net.
Есть предложения?

Dave Kreskowiak

Единственное, что я знаю о том, что делает уведомления, - это SQL Server, а не Express Edition.

Рейтинг:
0

Andrew Kelly

Возможно, добавьте триггеры Insert, Update, Delete в таблицу, чтобы записать строку в новую таблицу с двумя столбцами..

<uid строки изменен>
<тип изменения вставить/обновить/удалить>

Затем вы получаете доступ к этой таблице, и она сообщает вам, какие именно строки были вставлены, обновлены, удалены.


CHill60

Этому вопросу уже почти 7 лет! Придерживайтесь ответов на новые вопросы, где ОП все еще нуждается в помощи