Ru-MaNGOS

Вернуться   Ru-MaNGOS > Ядро > Патчи > Патчи на рассмотрении

Важная информация

Патчи на рассмотрении Рассматриваемые к принятию патчи

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.02.2011, 14:08   #1
zhenya
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 85
Сказал(а) спасибо: 5
Поблагодарили 42 раз(а) в 17 сообщениях
zhenya Скоро придёт к известности
По умолчанию [Database] Some SQL INSERT merge

Собственно. Есть предложение заменить в некоторых местах несколько инсертов одним.
например код
Код:
void Player::_SaveDailyQuestStatus()
{
    if (!m_DailyQuestChanged)
        return;

    // we don't need transactions here.
    CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",GetGUIDLow());
    for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
        if (GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx))
            CharacterDatabase.PExecute("INSERT INTO character_queststatus_daily (guid,quest) VALUES ('%u', '%u')",
                GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx));

    m_DailyQuestChanged = false;
}
на
Код:
void Player::_SaveDailyQuestStatus()
{
    if (!m_DailyQuestChanged)
        return;

    bool first_round = true;
    std::ostringstream ss;

    // we don't need transactions here.
    CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",GetGUIDLow());
    for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
    {
        uint32 quest_id = GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx);
        if (quest_id)
        {
            if (first_round)
            {
                ss << "INSERT INTO character_queststatus_daily (guid,quest) VALUES ";
                first_round = false;
            }
            // next new/changed record prefix
            else
                ss << ", ";
            ss << "(" << GetGUIDLow() << "," << quest_id << ")";
        }
    }

    // if something changed execute
    if (!first_round)
        CharacterDatabase.Execute( ss.str().c_str() );

    m_DailyQuestChanged = false;
}
Это поможет уменьшить размер транзакции для персонажей с кучей дейликов

Для викликов
Код:
void Player::_SaveWeeklyQuestStatus()
{
    if (!m_WeeklyQuestChanged || m_weeklyquests.empty())
        return;

    // we don't need transactions here.
    CharacterDatabase.PExecute("DELETE FROM character_queststatus_weekly WHERE guid = '%u'",GetGUIDLow());

    for (QuestSet::const_iterator iter = m_weeklyquests.begin(); iter != m_weeklyquests.end(); ++iter)
    {
        uint32 quest_id  = *iter;

        CharacterDatabase.PExecute("INSERT INTO character_queststatus_weekly (guid,quest) VALUES ('%u', '%u')", GetGUIDLow(), quest_id);
    }

    m_WeeklyQuestChanged = false;
}
меняем на
Код:
void Player::_SaveWeeklyQuestStatus()
{
    if (!m_WeeklyQuestChanged || m_weeklyquests.empty())
        return;

    // we don't need transactions here.
    CharacterDatabase.PExecute("DELETE FROM character_queststatus_weekly WHERE guid = '%u'",GetGUIDLow());

    for (QuestSet::const_iterator iter = m_weeklyquests.begin(); iter != m_weeklyquests.end(); ++iter)
    {
        if (first_round)
        {
            ss << "INSERT INTO character_queststatus_weekly (guid,quest) VALUES ";
            first_round = false;
        }
            // next new/changed record prefix
        else
            ss << ", ";

        ss << "(" << GetGUIDLow() << "," << (*iter) << ")";
    }

    // if something changed execute
    if (!first_round)
        CharacterDatabase.Execute( ss.str().c_str() );

    m_WeeklyQuestChanged = false;
}
и для месячных квестов
Код:
void Player::_SaveMonthlyQuestStatus()
{
    if (!m_MonthlyQuestChanged || m_monthlyquests.empty())
        return;

    // we don't need transactions here.
    CharacterDatabase.PExecute("DELETE FROM character_queststatus_monthly WHERE guid = '%u'", GetGUIDLow());

    for (QuestSet::const_iterator iter = m_monthlyquests.begin(); iter != m_monthlyquests.end(); ++iter)
    {
        uint32 quest_id = *iter;

        CharacterDatabase.PExecute("INSERT INTO character_queststatus_monthly (guid, quest) VALUES ('%u', '%u')", GetGUIDLow(), quest_id);
    }

    m_MonthlyQuestChanged = false;
}
меняем на
Код:
void Player::_SaveMonthlyQuestStatus()
{
    if (!m_MonthlyQuestChanged || m_monthlyquests.empty())
        return;

    bool first_round = true;
    std::ostringstream ss;

    // we don't need transactions here.
    CharacterDatabase.PExecute("DELETE FROM character_queststatus_monthly WHERE guid = '%u'", GetGUIDLow());

    for (QuestSet::const_iterator iter = m_monthlyquests.begin(); iter != m_monthlyquests.end(); ++iter)
    {
        if (first_round)
        {
            ss << "INSERT INTO character_queststatus_monthly (guid,quest) VALUES ";
            first_round = false;
        }
            // next new/changed record prefix
        else
            ss << ", ";

        ss << "(" << GetGUIDLow() << "," << (*iter) << ")";
    }

    // if something changed execute
    if (!first_round)
        CharacterDatabase.Execute( ss.str().c_str() );

    m_MonthlyQuestChanged = false;
}
критикуем

еще можно убрать кучу ифов _SaveSpells() и _SaveTalents()
, заменить свичем и убрать delete + insert (заменив Updatом) в случае PLAYERSPELL_CHANGED

Последний раз редактировалось zhenya; 28.02.2011 в 05:24.
zhenya вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
ghostpast (27.02.2011)
Старый 27.02.2011, 23:05   #2
Vladimir
MaNGOS Dev
 
Регистрация: 09.02.2010
Сообщений: 594
Сказал(а) спасибо: 315
Поблагодарили 438 раз(а) в 181 сообщениях
Vladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небес
По умолчанию

Вряд ли конечно в данных случаях можеть быть слишком длинаая строка запроса, но
лучше былобы если мы имели обобщенную функцию/накопительную_фабрику заполняющую такие запросы. В pdump есть пример где мы контролируем длину итогового запроса при генерации списка вещей вроде. Просто без прятания технической части код раздувается и становится менее понятным..
__________________
Так как устал объяснять знайте ICQ не пользуюсь
Vladimir вне форума   Ответить с цитированием
Старый 28.02.2011, 05:39   #3
zhenya
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 85
Сказал(а) спасибо: 5
Поблагодарили 42 раз(а) в 17 сообщениях
zhenya Скоро придёт к известности
По умолчанию

В случае daily может быть до 25.. (..,..).

по общему темлпею
в PlayerDump.cpp нашел
std::string CreateDumpString(char const* tableName, QueryResult *result)
вижу решение:
std::string CreateQuestSaveString(char const* tableName, uint32 guidlow, QuestSet quest) (но это не очень подойдет для daily квестов т.к. надо будет формировать QuestSet, можно конечно продублировать содермое полей в set...) или нужно что-то другое?

Последний раз редактировалось zhenya; 28.02.2011 в 05:49.
zhenya вне форума   Ответить с цитированием
Старый 28.02.2011, 13:11   #4
Ambal
MaNGOS Dev
 
Аватар для Ambal
 
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
Ambal Скоро придёт к известности
По умолчанию

Такая затея оправдана исключительно для текущего слоя БД, не использующего prepared statements. Когда появятся последние - придется "рожать все обратно" (с)
Ambal вне форума   Ответить с цитированием
Старый 28.02.2011, 16:49   #5
zhenya
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 85
Сказал(а) спасибо: 5
Поблагодарили 42 раз(а) в 17 сообщениях
zhenya Скоро придёт к известности
По умолчанию

работы по prepared statements идут ?
zhenya вне форума   Ответить с цитированием
Старый 28.02.2011, 17:27   #6
Ambal
MaNGOS Dev
 
Аватар для Ambal
 
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
Ambal Скоро придёт к известности
По умолчанию

Цитата:
Сообщение от zhenya Посмотреть сообщение
работы по prepared statements идут ?
идут, но медленно по двум причинам:
1) много забот по основному месту работы
2) совместимость с PostgreSQL без непосредственной реализации prepared statements в последней.

Пункт (2) особенно напрягает т.к. PostgreSQL в качестве DBMS для мангоса и так пользуется всего пара человек + планов по prepared statements для этой платформы у меня точно нет. Что, собственно, и вносит серьезные коррективы в API в плане необходимости использовать шаблоны и т.д.

Последний раз редактировалось Ambal; 28.02.2011 в 17:29.
Ambal вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
KiriX (01.03.2011)
Старый 28.02.2011, 17:42   #7
Vladimir
MaNGOS Dev
 
Регистрация: 09.02.2010
Сообщений: 594
Сказал(а) спасибо: 315
Поблагодарили 438 раз(а) в 181 сообщениях
Vladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небесVladimir Как свет с небес
По умолчанию

Цитата:
Сообщение от Ambal Посмотреть сообщение
Такая затея оправдана исключительно для текущего слоя БД, не использующего prepared statements. Когда появятся последние - придется "рожать все обратно" (с)
Ну тогда лучше не заморачиваться до prepared statements.
__________________
Так как устал объяснять знайте ICQ не пользуюсь
Vladimir вне форума   Ответить с цитированием
Старый 28.02.2011, 19:01   #8
zhenya
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 85
Сказал(а) спасибо: 5
Поблагодарили 42 раз(а) в 17 сообщениях
zhenya Скоро придёт к известности
По умолчанию

ага. ясно. ждемс
zhenya вне форума   Ответить с цитированием
Старый 03.03.2011, 11:40   #9
Ambal
MaNGOS Dev
 
Аватар для Ambal
 
Регистрация: 22.06.2010
Сообщений: 78
Сказал(а) спасибо: 24
Поблагодарили 71 раз(а) в 25 сообщениях
Ambal Скоро придёт к известности
По умолчанию

Если кому интересно, то можете взглянуть на мою ветку на гитхабе: https://github.com/Ambal/mangos/tree...red_statements.

Я почти закончил с объектной моделью для поддержки prepared statements и вчера даже успешно выполнил несколько запросов. Патч будет ориентировочно готов на следующей неделе. На данном этапе пока будет исключительно поддержка INSERT+DELETE+UPDATE запросов, позже добавим поддержку для SELECTов.
Ambal вне форума   Ответить с цитированием
3 пользователя(ей) сказали cпасибо:
Konctantin (03.03.2011), PSZ (03.03.2011), Vinolentus (03.03.2011)
Ответ


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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Merge remote branch 'origin/master' into 335 newsbot CMaNGOS Commits 0 02.07.2010 04:54
Merge branch 'master' into 330 newsbot CMaNGOS Commits 0 08.04.2010 03:40


Текущее время: 00:12. Часовой пояс GMT +3.


ru-mangos.ru - Русское сообщество MaNGOS
Главная цель проекта MaNGOS - обучающая, поэтому разрешается использовать исходный код и собранную программу только для образовательных целей.
Вы не можете использовать MaNGOS в коммерческих целях, а также не разрешается устанавливать публичные серверы на базе MaNGOS.
Любое копирование материалов, информации в любом виде без указания источника - форума Ru-MaNGOS будет считаться нарушением авторских прав и нарушением Уголовного Кодекса РФ, ст. 146 ст. 147.
Перевод vBulletin: zCarot