1. Акция на весь декабрь! Получай оплату х2 за уникальные статьи, объемом от 200 слов, если в заголовке темы и теле статьи присутствует слово Python
    Скрыть объявление

Оптимизация внесения данных в БД

Тема в разделе "Delphi - Базы данных", создана пользователем Lunatikus, 3 июл 2007.

Статус темы:
Закрыта.
  1. Lunatikus

    Lunatikus Гость

    БД Access 2002.
    Delphi 7.

    Вот цикл из проги:
    Код (Text):
    i:=10;

    ADOQ1.open;
    ostatok:=ADOQ1.fields[0].asfloat;

    ADOQ2.SQL.Clear;
    ADOQ2.SQL.append('UPDATE DEAL SET ostatok=:ostatok WHERE univer=:univer AND data=:data');

    while i>0 do
    begin
    i=i-1;
    ADOQ1.next;
    ostatok:=ostatok+ADOQ1.fields[1].asfloat+ADOQ1.fields[2].asfloat+ADOQ1.fields[3].asfloat;
    ADOQ2.parameters[0].value:=ostatok;
    ADOQ2.parameters[1].value:=ADOQ1.fields[4].asstring;
    ADOQ2.parameters[2].value:=ADOQ1.fields[5].asdatetime;
    ADOQ2.execSQL;
    end;
    как бы его оптимизировать?а то надо один раз выполнить все это не по 10 строкам а по 500тысячам,а со скоростью 1 строка в 2 секунды это будет очень долго...подскажите,что не так?и как можно оптимизировать?Спасибо за уделенное время!
     
  2. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    <!--QuoteBegin-Lunatikus+3:07:2007, 14:41 -->
    <span class="vbquote">(Lunatikus @ 3:07:2007, 14:41 )</span><!--QuoteEBegin-->подскажите,что не так?
    [snapback]71170" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Такие запросы нужно делать на стороне сервера, т.е. необходимо написать один (!!!) запрос, обновляющий все записи. Эти ваши постоянные выборки-вставки отрицательно сказываются на быстродействии. А про 500 тыщ это серьезно? При таких объемах уже давно пора отказаться от Access
     
  3. Lunatikus

    Lunatikus Гость

    тогда вопрос-что позволит в mySQL сделать это быстрее?И каким образом сделать один запрос?У меня ADOQ1 итак двойной left joinовый по трем таблицам.Я даже не представляю как результаты его совместить с updateом...ну новичок я,новичок...потому и прошу совета.В принципе,я собираюсь делать в итоге на mySQL,но пока не имею возможности и приходиться костяк проги делать с accessom.
     
  4. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Покажи структуру своих таблиц и расскажи что надо сделать. Может помогу...
     
  5. Lunatikus

    Lunatikus Гость

    DEAL:
    data PK
    univer PK
    ostatok
    prognoz

    V_PUTI:
    fil PK
    univer PK
    kolc
    data PK

    ZAK:
    n_zak PK
    org
    univer
    razmer
    data_zak
    manager
    active
    data_sozd

    А сделать надо следующее:
    Я получаю такой набор данных:

    DEAL_VIRTUAL:
    data (DEAL)
    univer(DEAL)
    ostatok
    prognoz(DEAL)
    kolc (V_PUTI)(суммируются все kolc(V_PUTI) по univer и data и совмещается с DEAL по полям univer и data)
    razmer (ZAK)(суммируются все razmer(ZAK) по univer и data и совмещается с DEAL по полям univer и data)
    C ним я делаю уже расчеты значения поля ostatok:
    поле ostatok ,берется из DEAL(оно имеет значения только на текущую дату data,после чего расчитываются следующие строки как указано в коде:eek:statok(next)=ostatok+kolc-prognoz-razmer)
    после вычислений,результат надо занести в DEAL,чтобы получить заполненную таблицу значениями ostatok.
    Т.е. все,ради чего я это делал-чтобы заполнить поле ostatok(DEAL) на основе данных из ZAK,V_PUTI.
     
  6. Lunatikus

    Lunatikus Гость

    Перешел на MS SQL server 2000.Скорость возросла в дцать раз.Топик можно закрыть.

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

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Для: Lunatikus
    Ой, забыл про твой запрос... Сейчас попробую написать
     
  8. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    У-ф-фф... Запарился:( Последовательность написания запроса такова:

    1. Сделаем запрос на получение полей kolc и razmer
    Код (Text):
    SELECT v.data as data, v.univer as univer, sum(v.kolc) as kolc, sum(z.razmer) as razmer
    FROM Deal d
    LEFT FOIN V_Puti v ON d.data = v.data AND d.univer = v.univer
    LEFT JOIN Zak z ON d.data = z.data_zak AND d.univer = z.univer
    GROUP BY v.kolc, z.razmer
    2. Вычислим значение поля ostatok
    Код (Text):
    SELECT d.data as data, d.univer as univer, (d.ostatok + dv.kolc – dv.razmer) as ostatok
    FROM Deal d LEFT JOIN
    (
    SELECT v.data as data, v.univer as univer, sum(v.kolc) as kolc, sum(z.razmer) as razmer
    FROM Deal d
    LEFT FOIN V_Puti v ON d.data = v.data AND d.univer = v.univer
    LEFT JOIN Zak z ON d.data = z.data_zak AND d.univer = z.univer
    GROUP BY v.kolc, z.razmer
    ) Deal_Virtual dv ON ON d.data = dv.data AND d.univer = dv.univer
    3. Напишем результирующий запрос на обновление
    Код (Text):
    UPDATE Deal SET ostatok =
    (
    SELECT Data.ostatok
    FROM Deal LEFT JOIN
    (
    SELECT d.data as data, d.univer as univer, (d.ostatok + dv.kolc – dv.razmer) as ostatok
    FROM Deal d LEFT JOIN
    (
    SELECT v.data as data, v.univer as univer, sum(v.kolc) as kolc, sum(z.razmer) as razmer
    FROM Deal d
    LEFT FOIN V_Puti v ON d.data = v.data AND d.univer = v.univer
    LEFT JOIN Zak z ON d.data = z.data_zak AND d.univer = z.univer
    GROUP BY v.kolc, z.razmer
    ) Deal_Virtual dv ON ON d.data = dv.data AND d.univer = dv.univer
    ) UpdatedValues
    ON Deal.data = UpdatedValues.data AND Deal.univer = UpdatedValues.univer
    )
    Ты не привел правила для расчета поля prognoz поэтому я его не учитывал. Также неочевидно по какой дате идет связь с таблицей Zak, поэтому я использовал data_zak. Скорее всего с первого раза не заработает, так что спрашивай если что. Советую отлаживать по пунктам
     
  9. Lunatikus

    Lunatikus Гость

    Я доделывал свой вариант,потому так долго не отвечал.Потом попробовал твой враиант-ушло правда время чтобы его подправить-ошибки были.В итоге получилось практически одно быстродействие-мой вариант все с теми же двумя запросами-работа с одним и периодическая запись данных с помощью другого.К тому же у меня планируется добавление еще нескольких операций записи-а это значит еще большее усложнение в твоем варианте-в моем же просто добавлю отдельный простенький запрос.Ты,конечно же,прав,что надо использовать единый запрос,но для меня в данный момент это нецелесообразно.Спасибо за уделенное время и помощь!
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей