Форум по 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:16
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

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

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

Последний раз редактировалось Mrak, 20.06.2013 в 10:19.
Ответить с цитированием
  #4  
Старый 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 на каждый второй, а как нибудь проще?
Ответить с цитированием
  #5  
Старый 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)
  #6  
Старый 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 секунду?
Ответить с цитированием
  #7  
Старый 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.
Ответить с цитированием
  #8  
Старый 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 записями

нет, такого быть не может
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")
Ответить с цитированием
  #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)
  #10  
Старый 20.06.2013, 11:03
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Как я понял основная задача сделать просто поудобнее способ обращения к данным? Тогда зачем вам вообще MSSQL? Создайте таблицу прямо в MySQL. Там-же создайте хранимку или тригер на добавление, которые автоматом будут заполнять вашу таблицу при появлении новых данных.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
Этот пользователь сказал Спасибо Страдалецъ за это полезное сообщение:
alexusankov (20.06.2013)
  #11  
Старый 20.06.2013, 11:08
Аватар для alexusankov
alexusankov alexusankov вне форума
Новичок
 
Регистрация: 27.08.2012
Сообщения: 78
Версия Delphi: C++/Delphi 2010
Репутация: 10
По умолчанию

Цитата:
Сообщение от Страдалецъ
Как я понял основная задача сделать просто поудобнее способ обращения к данным? Тогда зачем вам вообще MSSQL? Создайте таблицу прямо в MySQL. Там-же создайте хранимку или тригер на добавление, которые автоматом будут заполнять вашу таблицу при появлении новых данных.
Т.е. вы хотите сказать, что можно организовать таблицу прямо в MySQL, и как то это органиовать, чтобы нужные мне приходящие данные дублировались в моей таблице, в моем формате?? С помощью чего это организуется? Загуглить 'хранимка' не удалось.
Пользовать MySQL дальше того что есть сейчас к сожалению не могу, т.к. бюрократия,идиотизм, и политика запрещают.
И отказаться не могу, т.к. софт который присылает туда данные работает лишь с MySQL, и писался он не мной (
Ответить с цитированием
  #12  
Старый 20.06.2013, 11:14
Аватар для Mrak
Mrak Mrak вне форума
Местный
 
Регистрация: 26.01.2013
Адрес: МО
Сообщения: 438
Версия Delphi: XE2
Репутация: 17
По умолчанию

Цитата:
Сообщение от alexusankov
Т.е. вы хотите сказать, что можно организовать таблицу прямо в MySQL, и как то это органиовать, чтобы нужные мне приходящие данные дублировались в моей таблице, в моем формате?? С помощью чего это организуется? Загуглить 'хранимка' не удалось.
Пользовать MySQL дальше того что есть сейчас к сожалению не могу, т.к. бюрократия,идиотизм, и политика запрещают.
И отказаться не могу, т.к. софт который присылает туда данные работает лишь с MySQL, и писался он не мной (

Ну так и работайте с мускл, чем он плох

хранимка - хранимая процедура. в данном случае лучше триггер на INSERT
__________________
Я за здоровый экстрим!
Спасибо за "спасибо")
Ответить с цитированием
Этот пользователь сказал Спасибо Mrak за это полезное сообщение:
alexusankov (20.06.2013)
  #13  
Старый 20.06.2013, 11:22
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Определитесь сначала с правами на создание, изменение в MySQL. Если вы можете создавать новые таблицы и изменить структуру проблемной базы, то тогда все просто... ну почти. Просто таблиц дофига, но скриптом можно разом все это изменить.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #14  
Старый 20.06.2013, 11:33
Аватар для Yurk@
Yurk@ Yurk@ вне форума
Специалист
 
Регистрация: 07.09.2007
Адрес: Украина, г. Днепропетровск
Сообщения: 892
Версия Delphi: 7 + ОгнеПтица
Репутация: выкл
По умолчанию

Цитата:
А пример запроса, можно?
ну в Firebird я бы попробовал как-то так:
Код:
EXECUTE BLOCK
AS
  DECLARE VARIABLE i INTEGER;
  DECLARE VARIABLE old_tabl VARCHAR(15);
  DECLARE VARIABLE text VARCHAR(255);
BEGIN
  i = 1;

  WHILE (i <= 300) DO
  BEGIN
    text = 'INSERT INTO new_table SELECT <список полей> FROM ('||old_tabl || i||');';

    EXECUTE STATEMENT text;
    i = i + 1;
  END

END;
возможно в MySQL\MS SQL есть команда подобная EXECUTE STATEMENT
__________________
Поживу - увижу, Доживу - узнаю, Выживу - учту.
[P.S.]->Выражая благодарность за помощь - Вы получаете шанс на помощь в следующий раз

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

Для полноценной работы с MySQL, его для начала нужно выпустить в сеть, для чего нужно открыть ему порты, для чего нужно править локальные политики, для которых нужно лезть в GPO, для которого нужен доступ к контроллеру домена, с правами правки GPO / GPOE для домена.
В итоге ларец в зайце, в доме который построил Джек.
Не вариант работать с MySQL.
Сейчас испытаю вариант с заменой LIKE на диапазон..
И буду гуглить 'хранимые процедуры'

Последний раз редактировалось alexusankov, 20.06.2013 в 11:42.
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

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

ВКонтакте   Facebook   Twitter