Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 20.06.2013, 09:48
Аватар для alexusankov
alexusankov alexusankov вне форума
Новичок
 
Регистрация: 27.08.2012
Сообщения: 78
Версия Delphi: C++/Delphi 2010
Репутация: 10
По умолчанию низкая скорость запросов (

Добрый день, товарищи. Набросал небольшую утилиту, все работает прекрасно, кроме одного - скорости.
Суть проста - программа берет ровно 300 записей из MySQL, и записывает их в Microsoft SQL. Время выполнения - 12 мин.
Вкратце : в первой базе есть около 700 таблиц, лишь 300 из них заполняются. Таблицы зовут как : 'T' + номер железяки. т.е. семьсот таблиц T1 - T700.
В каждой из таблиц, есть столбцы : время, датчик, значение. Каждый час в таблицу пишется время, номер датчика (от 1 до 28) и значение этого датчика.
В другой базе данных, в которую я и перетаскиваю данные, сделано чуть чуть по другому - там вместо трехсот таблиц, используется одна, в ней есть : имя, время, и 28 столбцов сотв-щих каждому датчику.
Программа выбирает данные из первой базы, и пишет во вторую. Время это занимает - около 12-15 минут . Это же жесть.
Может, я пишу код как муд*к?
Сама процедура :
Код:
for index := 1 to 728 do begin  //читаем 720 таблиц t1 - t720
  Application.ProcessMessages();
  Line := '';
  QMySQL.SQL.Clear();  // из базовой таблицы берем имя железяки, которое соответствует T + index
  QMySQL.SQL.Text := 'SELECT Name FROM rstt WHERE hO  = ' + IntToStr(index);
  QMySQL.Open();
  Device := QMySQL.FieldValues['Name'];
   i := 0; // теперь в таблице этой железяки мы 28 раз берем значения ее 28ми датчиков за указанное время
  while i < 28 do begin
    QMySQL.SQL.Clear();
    QMySQL.SQL.Text := 'SELECT AV FROM t' + IntToStr(index) + ' WHERE (Time LIKE ' + #39 + GetValues('Data') + ' ' + GetValues('Hour') + '%' +  #39 + ' ) AND (Sen = ' + IntToStr(i) + ')';
    QMySQL.Open();
    if QMySQL.FieldValues['AV'] <> null then L[i] := FloatToStr(RoundTo(StrToFloat(QMySQL.FieldValues['AV']),-2));
    if QMySQL.FieldValues['AV'] = null then  i := 50;
    QMySQL.Close;
    Inc(i); // и кладем их в массив
  end;
  if i < 50 then begin
    QMsSQL.SQL.Clear(); // раскладываем массив в запрос и посылаем в Ms SQL
    Vals := '(' + #39 + Copy(Device,Pos('s7',Device) + 6,5) + #39 + ',' + #39 + GetValues('Data') + #39 + ',' + #39 + GetValues('Hour') + #39 ;
    for z := 0 to 27 do Vals := Vals + ',' + #39 + L[z] + #39;
    Vals := Vals + ')';
    QMsSQL.SQL.Text := 'INSERT INTO dbo.newbase' + ' (ObName,Data,Time,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22,s23,s24,s25,s26,s27,s28) VALUES ' + Vals;
    QMsSQL.ExecSQL();
     end;
end;

Последний раз редактировалось alexusankov, 20.06.2013 в 09:57.
Ответить с цитированием
  #2  
Старый 20.06.2013, 10:16
Аватар для Yurk@
Yurk@ Yurk@ вне форума
Специалист
 
Регистрация: 07.09.2007
Адрес: Украина, г. Днепропетровск
Сообщения: 892
Версия Delphi: 7 + ОгнеПтица
Репутация: выкл
По умолчанию

как-то все сложно)
не проще ли в MySQL создать такую же таблицу как и в MS SQL и перелить все данные из таблиц в нее, а потом уже в одной (общей) таблицы почистить.
и уже потом перелить всё готовое в MS SQL!
__________________
Поживу - увижу, Доживу - узнаю, Выживу - учту.
[P.S.]->Выражая благодарность за помощь - Вы получаете шанс на помощь в следующий раз
Ответить с цитированием
  #3  
Старый 20.06.2013, 10:34
Аватар для alexusankov
alexusankov alexusankov вне форума
Новичок
 
Регистрация: 27.08.2012
Сообщения: 78
Версия Delphi: C++/Delphi 2010
Репутация: 10
По умолчанию

Цитата:
Сообщение от Yurk@
как-то все сложно)
не проще ли в MySQL создать такую же таблицу как и в MS SQL и перелить все данные из таблиц в нее, а потом уже в одной (общей) таблицы почистить.
и уже потом перелить всё готовое в MS SQL!
Интереснейшая мысль. Вы хотите сказать, что если делать Селект из старых таблиц, и Инсерт в одну новую , в MySQL, и после готовую тянуть на MS SQL, то процесс пойдет быстрее?
А пример запроса, можно?
А может такое быть, что скорость режет сама СУБД MySQL? Т.е. 1 запрос на 1 секунду?
Ответить с цитированием
  #4  
Старый 20.06.2013, 10:42
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

Цитата:
Сообщение от alexusankov
Интереснейшая мысль. Вы хотите сказать, что если делать Селект из старых таблиц, и Инсерт в одну новую , в MySQL, и после готовую тянуть на MS SQL, то процесс пойдет быстрее?
А пример запроса, можно?
А может такое быть, что скорость режет сама СУБД MySQL? Т.е. 1 запрос на 1 секунду?
ну естественно 1 таблица с миллионом записей лучше, чем 700 со 100 записями

нет, такого быть не может
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")
Ответить с цитированием
  #5  
Старый 20.06.2013, 10:16
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

Таблицы индексировались?
избавляйся от LIKE
это на локалхосте?

[off] это потому, что ава такая)) [/off]
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")

Последний раз редактировалось Mrak, 20.06.2013 в 10:19.
Ответить с цитированием
  #6  
Старый 20.06.2013, 10:29
Аватар для alexusankov
alexusankov alexusankov вне форума
Новичок
 
Регистрация: 27.08.2012
Сообщения: 78
Версия Delphi: C++/Delphi 2010
Репутация: 10
По умолчанию

Цитата:
Сообщение от Mrak
Таблицы индексировались?
не знаю, что сие значит, но уникальные поля есть и там и там.
Цитата:
избавляйся от LIKE
проблематично, т.к. формат времени в первой базе неудобен
Цитата:
это на локалхосте?
да
P.s. структуру и запись в MySQL организовывал не я, и контролировать ее соответственно не могу...
Судя по логу в консоли, ровно на 1 цикл index, уходит ровно секунда. Т.е. все танцы с бубном - 720 секунд.
Печалька
P.s.s быть может можно как нибудь в SQL хитрым запросом прочитать 720 таблиц, и дальше уже возиться с датасетом? Не корячиться, и не делать 720 запросов + по 28 на каждый второй, а как нибудь проще?
Ответить с цитированием
  #7  
Старый 20.06.2013, 10:34
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

на локалхосте должно летать, если проиндексировать (смотри гугл)
конструкция LIKE тот еще тормоз (ну, в принципе, оно и понятно)
придумай как его убрать. в чем трабл с неудобностью формата времени?

> быть может можно как нибудь в SQL хитрым запросом прочитать 720 таблиц, и дальше уже возиться с датасетом? Не корячиться, и не делать 720 запросов + по 28 на каждый второй, а как нибудь проще?
по идее, на стороне сервера это будет быстрее, чем грузить все в датасеты и из них брать
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")

Последний раз редактировалось Mrak, 20.06.2013 в 10:37.
Ответить с цитированием
Этот пользователь сказал Спасибо Mrak за это полезное сообщение:
alexusankov (20.06.2013)
  #8  
Старый 20.06.2013, 10:42
Аватар для alexusankov
alexusankov alexusankov вне форума
Новичок
 
Регистрация: 27.08.2012
Сообщения: 78
Версия Delphi: C++/Delphi 2010
Репутация: 10
По умолчанию

Цитата:
Сообщение от Mrak
на локалхосте должно летать, если проиндексировать (смотри гугл)
конструкция LIKE тот еще тормоз (ну, в принципе, оно и понятно)
придумай как его убрать. в чем трабл с неудобностью формата времени?
в MySQL это поле хранится в таком виде : '2013-06-20 08:05:40'
Т.е. datetime видать. Я же, знаю лишь час когда проходило обновление таблиц
запись типа WHERE time = '2013-06-20 08' результата не даст. Только, если попробовать WHERE (time > '2013-06-20 08') AND (time < '2013-06-20 09').
Судя по консоли - да, запрос чуть быстрее бегает...
Сейчас перепишу и попробую

Последний раз редактировалось alexusankov, 20.06.2013 в 10:46.
Ответить с цитированием
  #9  
Старый 20.06.2013, 10:46
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

Цитата:
Сообщение от alexusankov
в MySQL это поле хранится в таком виде : '2013-06-20 08:05:40'
Т.е. datetime видать. Я же, знаю лишь час когда проходило обновление таблиц
запись типа WHERE time = '2013-06-20 08' результата не даст. Только, если попробовать WHERE (time > '2013-06-20 08:') AND (time < '2013-06-20 09').
Сейчас проверю
Код:
WHERE (time > '2013-06-20 08:00:00') AND (time < '2013-06-20 09:00:00')
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")
Ответить с цитированием
Этот пользователь сказал Спасибо Mrak за это полезное сообщение:
alexusankov (20.06.2013)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:40.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter