PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи

Страниц (21): В начало « ... 13 14 15 16 17 18 19 20 [21]

> Найдено сообщений: 305
Phantik Отправлено: 19 Августа, 2009 - 17:48:54 • Тема: Оптимизация запроса UPDATE в MySQL • Форум: SQL и Архитектура БД

Ответов: 8
Просмотров: 76
Прошу всех прощения за то что из мухи сделал слона. Вообщем разобрался окончательно. Правильный ответ был:

alter table wins add index xxx (LID,DrawNum,TckNum);

И все работает мгновенно.

А до этого меня приглючило что будет достаточно только PRIMARY KEY(`LID`,`DrawNum`,`Module`,`Tour`,`TckNum`)
Phantik Отправлено: 19 Августа, 2009 - 15:30:39 • Тема: Оптимизация запроса UPDATE в MySQL • Форум: SQL и Архитектура БД

Ответов: 8
Просмотров: 76
Champion пишет:
Самым быстрым образом апдейт выполнится, когда есть индексы по тому, что участвует в WHERE и нет индексов по всему остальному. Первое гораздо значительнее. Выводы делайте сами.
(Добавление)
Phantik пишет:
1) Попробовать BLOB поле заменить на текстовое ибо тип хранимых данных это позволяет сделать
Обязательно.
(Добавление)
А вообще, написано очень много.


BLOB на char(n) заменил. Прирост получился несущественный.
Все поля которые в WHERE являются составным Primary Key т.е. я так понимаю индексированы автоматически. Поля которые обновляются - без индексов.

Есть аналогичная структура таблиц\запросов под MSSQL и MSAccess - запрос Update работает на порядок быстрее. Пытаюсь того же добиться на MySQL.
(Добавление)
Stierus пишет:
а экслэйн этого запроса что выдает?


id 1

select_type SIMPLE

table wins

type ref

possible_keys PRIMARY

key PRIMARY

key_len 4

ref const,const

rows 103610

Extra Using Where

Я правда не знаю какой из этого следует вывод Не понял
Phantik Отправлено: 19 Августа, 2009 - 14:35:13 • Тема: Оптимизация запроса UPDATE в MySQL • Форум: SQL и Архитектура БД

Ответов: 8
Просмотров: 76
Сразу приношу извинения за большой текст. Задавал этот вопрос кратко на другом форуме, но людям не хватило информации, поэтому пришлось выложить более подробно:

Так устроен типичный запрос на поиск\проверку билета:
CODE (text):
скопировать код в буфер обмена
  1.  
  2. SELECT wins.LID,wins.DrawNum,wins.Module,wins.Tour,wins.TckNum,wins.PayDT,wins.WorkST,wins.CurTax,wins.FieldCont,
  3. summ.Money, summ.Descr1, summ.Descr2,
  4. mods.ModType, mods.LongName, mods.ShortName
  5. FROM wins  
  6. INNER JOIN summ ON (wins.LID=summ.LID AND wins.DrawNum=summ.DrawNum AND wins.Tour=summ.Tour)
  7. INNER JOIN mods ON (wins.LID=mods.LID AND wins.DrawNum=mods.DrawNum AND wins.Module=mods.Module)
  8. WHERE wins.LID=1 AND wins.DrawNum=532 AND wins.TckNum=358015"


Теперь описание таблиц участвующих в запросе.

Таблица wins. В ней хранятся все выигрыши. Количество записей всреднем 3-5 миллионов.
CODE (text):
скопировать код в буфер обмена
  1.  
  2. CREATE TABLE `wins` (
  3.   `LID` smallint(6) unsigned NOT NULL,                         // Код лотереи        
  4.   `DrawNum` smallint(6) unsigned NOT NULL,                // Номер тиража
  5.   `Module` smallint(6) unsigned NOT NULL,                    // Код типа розыгрыша
  6.   `Tour` smallint(6) unsigned NOT NULL,                        // Тур в котором выиграл билет
  7.   `TckNum` int(11) unsigned NOT NULL,                        // Номер билета
  8.   `PayDT` double DEFAULT 0.0,                                    // Дата\Время оплаты (если выигрыш был оплачен)
  9.   `WorkST` smallint(6) unsigned NOT NULL,                   // Номер рабочей станции оплатившей билет
  10.   `CurTax` smallint(6) unsigned NOT NULL,                    // Налог в % который был уплачен с выигрыша
  11.   `FieldCont` BLOB,                                                     // Игровое поле билета.
  12.     PRIMARY KEY(`LID`,`DrawNum`,`Module`,`Tour`,`TckNum`)
  13. ) ENGINE=MyISAM;


Таблица summ. В ней хранятся описания призов и денежные суммы призов. Записей в среднем 3-5 тысяч.
Связана с таблицей wins по полям LID, DrawNum, Module, Tour. Связь один(summ) ко многим(wins). Связь логическая, физически (средствами СУБД) не реализована.
CODE (text):
скопировать код в буфер обмена
  1.  
  2. CREATE TABLE `summ` (
  3.   `LID` smallint(6) unsigned NOT NULL,                            // Код лотереи
  4.   `DrawNum` smallint(6) unsigned NOT NULL,                   // Номер тиража
  5.   `Module` smallint(6) unsigned NOT NULL,                       // Код типа розыгрыша
  6.   `Tour` smallint(6) unsigned NOT NULL,                          //  Тур
  7.   `Money` bigint(20) unsigned NOT NULL,                         // Сумма
  8.   `Descr1` char(64)  DEFAULT NULL,                                // Текстовое описание приза
  9.   `Descr2` char(64)  DEFAULT NULL,                                // Текстовое описание приза №2
  10.    PRIMARY KEY(`LID`,`DrawNum`,`Module`,`Tour`)
  11. ) ENGINE=MyISAM;
  12.  


Таблица mods. В ней хранятся типы розыгрыша(особенности правил игры в определенном тираже)
Записей в среднем до 1000.
Связана с таблицей wins по полям LID,DrawNum,Module
CODE (text):
скопировать код в буфер обмена
  1.  
  2. CREATE TABLE `mods` (
  3.   `LID` smallint(6) unsigned NOT NULL,
  4.   `DrawNum` smallint(6) unsigned NOT NULL,
  5.   `Module` smallint(6) unsigned NOT NULL,
  6.   `ModType` smallint(6) unsigned NOT NULL,
  7.   `LongName` char(64)  DEFAULT NULL,
  8.   `ShortName` char(32)  DEFAULT NULL,
  9.   PRIMARY KEY (`LID`,`DrawNum`,`Module`)
  10. ) ENGINE=MyISAM;
  11.  


Так вот. Первый запрос выполняется приемлимо быстро. В среднем 1-50 мили сек. Особенности работы оператора состоят в том что если билет выигрышный(т.е. первый запрос вернулся не пустым), то ему надо зафиксировать оплату билета. Т.е. проапдейтить поля PayDT, WorkST, CurTax в таблице wins. Для этого выполняется следующий запрос:
CODE (text):
скопировать код в буфер обмена
  1.  
  2. UPDATE wins SET PayDT=40044.4448122338,WorkST=1,CurTax=0
  3. WHERE LID=1 AND DrawNum=532 AND TckNum=358015
  4.  


Так вот. ПРоблема в том что этот запрос уже выполняется по времени порядка 1 секунды. Что абсолютно неприемлимо ибо скорость оператора по вводу билетов может достигать 3-4 билетов в секунду. Отсюда следует собственно вопрос, как существенно ускорить запрос на изменение. Уверен что это возможно т.к. базы аналогичной структуры в СУБД Access и MSSQL выполняют такой запрос практически на порядок быстрее.

Теперь какие у меня есть мысли по всему этому.
1) Попробовать BLOB поле заменить на текстовое ибо тип хранимых данных это позволяет сделать.
2) С учетом пункта 1) (или без учета) вынести Blob(текстовое) поле в другую таблицу. Связь будет по LID,DrawNum,TckNum
3) Создать временную таблицу Tmp со структурой аналогичной таблице wins и все фиксации оплаты заносить туда с Помощью INSERT. (Протестил добавление - оно работает приемлемо быстро порядка 500 записей в секунду). И далее(например перед закрытием программы) либо писать хитрый запрос на вроде(проапдейтить в wins те записи которые присутствуют в Tmp). Такой запрос с помощью SQL вроде можно написать. Либо запускать параллельный поток, который будет брать запись из Tmp апдейтить соответствующую в wins и удалять из Tmp.
4) Мне кажется, что есть среди настроек MySQL те, которые отвечают за работу с кешем. Что бы апдейты записывались не напрямую в базу(А судя по времени, у меня возникает ощущение что СУБД пишет напрямую), а через кеш. Очень надеюсь что знающие люди подскажут эти настройки.
Phantik Отправлено: 01 Июля, 2009 - 13:42:24 • Тема: Работа серверной стороны без запросов клиентов. • Форум: Программирование на PHP

Ответов: 5
Просмотров: 481
Спасибо за советы. Впринципе свой метод тоже неплох правда, видимо, излишне будет нагружать Апач. Я вот думаю еще о таком варианте, как написать исполняемый клиент на C++ Builder(надо только скачать дополнительные дрова для конекта с MySQL) Ну а в проге по таймеру анализировать таблицы и вносить изменения . Правда тут есть свои нюансы - экзешник будет работать под виндой т.е. на юниксовых хостингах я не смогу запускать свой проект. И даже если хост виндовый, позволит ли фирма-хостер запускать на своих серваках различные мои экзешники? Так же пока не совсем представляю как будет выглядеть удаленное управление мои экзешником.


Ладно.... Пока все это обсуждалось, у меня появилась еще одна проблема. Решить я ее смог как то случайно, но вот смысла, почему так происходит, не понял.
Вообщем тот файл control.php к которому каждые несколько секунд обращалась страница таймер(см. 1ый пост) имел следущую структуру:

<html>
<head>
</head>
<body>
<?php

function ABC($ID)
{
$query = "SELECT ......";
$resylt = mysql_query($query, $link);
//.............................
// Другие действия с базой
//.............................
}


// Некие действия с базой
//.............................. ..
$ID = line['Player_ID'];
switch($a)
{
case 1 : ABC($ID);
break;
case 2: //........
break;
//......................

?>

<script> location.href="timer.html"</script>
</body>
</html>

Проблема была в следущем: Выполнялись все действия в PHP коде(Некие действия с базой) но в функцию ABC() скрипт не заходил ни в какую. "Другие действия с базой" - не выполнялись. Мучался пол дня, код заработал только тогда когда заменил строку

<script> location.href="timer.html"</script>

на

<script> setTimeout("location.href='timer.html'",3000)</script>

Отсюда сделал вывод что пересылка на другую страницу выполнялась раньше чем вызывалась функция. Причем странно еще то, что весь PHP код успевал выполняться до пересылки, кроме кода внутри функции. Отложив пересылку на 3 секунды, стал успевать выполняться весь код.
кто знает в чем тут фича? Почему код выполняется как-то непоследовательно совсем?
спасет ли ситуацию замена строки
<script> setTimeout("location.href='timer.html'",3000)</script>

на <?php echo '<script> location.href="timer.html"'; </script>
если разместить ее в самом конце основного PHP кода?
Phantik Отправлено: 30 Июня, 2009 - 14:51:20 • Тема: Работа серверной стороны без запросов клиентов. • Форум: Программирование на PHP

Ответов: 5
Просмотров: 481
Здравствуйте форумчане. Я тут человек новый, поэтому прошу не судить строго за, возможно, примитивные вопросы.
Проблема в следующем. В контексте создания браузерной игры столкнулся с задачей необходимости обработки данных на сервере в ситуациях когда от клиентов не поступает запростов вообще, но при этом обрабатывать данные нужно. Банальный пример: Я отправляю свою армию на врага и прийти она должна допустим через 3 часа. Рассматривается ситуация, когда ни меня ни противника(на которого я отправил армию) нету у компа вообще. Но тем не менее, должен отработать скрипт который обсчитает битву и запишет в базу данных всю информацию о результатах данного события(битвы).

Я только недавно начал изучать PHP и пока у меня нет идеи как реализовать такую задачу. У меня пока сложилось жесткое представление об работе PHP связанное с четкой логикой: запрос клиента -> ответ сервера. Т.е. у меня каждая страница делится на 2 состовляющие:
1) html(php) страница - которую показываем клиенту.
2) php страница обрабатывающая страницу из пункта 1.
(иногда пункты 1 и 2 совмещены физически в одной странице)

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

Я немного погорячился, сказав что нету идеи. Идея есть и я ее даже реализовал и она работает следующим образом. Все события которые должны произойти сами по себе в некоторое определенное время, независимо от запроса пользователя, я записываю в специальную таблицу MySQL. Одно из полей в этой таблице - это время, когда надо обработать данное событие. Дальше я сделал страничку не входящую в сайт самой игры, но каждые несколько секунд (через JavaScript таймер ) она обращается к некому php файлу. В этом файле делается запрос к таблице событий и если в ней есть записи событий время которых настало, они в цикле обрабатываются соответствующими функциями, после чего результаты записываются в базу.

Вообщем задачу то я выполнил, но как-то это все каряво выглядит. Наверняка в PHP есть возможность все это реализовать без левой странички, непрерывно бомбящей сервер своими запросами. Мне кажется что все это можно реализовать гораздо проще, и красивее какими-нить возможностями PHP про которые я еще не знаю. Кто-нибудь может мне посоветовать в какой области копать? Наверняка многие уже сталкивались со схожими задачами.
Заранее благодарен за ответы.

Страниц (21): В начало « ... 13 14 15 16 17 18 19 20 [21]
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB