2013-12-09 2 views
1

У меня есть сценарий назначения в php + mysql.Подключение к MySQL внутри цикла fooreach замедляет мою страницу php

В скрипте у меня 6 столбцов, и каждый столбец имеет 64 строки, равные 384 полям. Для каждого поля у меня есть одно соединение mysql_query, которое выводит 384 подключения к MySQL. есть ли способ сделать этот скрипт более эффективным и быстрым ??? Также я хочу добавить, что этот скрипт работает на Xeon 3.4ghz 4 ядра 8gb ram server, и у меня есть задержка для этой страницы около 20-25 секунд. но на других страницах, где я не использую цикл, у меня очень быстрые результаты, даже если я перечислю несколько сотен строк.

Это мой код:

$listebolum=mysql_query("SELECT * FROM bolum WHERE randevu='ok' AND sube='".$_SESSION[ksube]."' ORDER BY id ASC"); 
while($listeboluml=mysql_fetch_array($listebolum)) { 
    $basla=$danas; 
    echo "<div style=\"position:relative; width:".$sirina."%; float:left; border-right:solid 1px #9a4b9d;\">"; 
    for($ra=$danas; $ra<$danasson; $ra=($ra+900)) { 

     $uzmirandevu=mysql_query("SELECT randevu.id AS rid, randevu.bitis AS rbitis, randevu.baslama AS rbaslama, randevu.notum AS rnotum, randevu.hizmetler AS rhizmetler, musteri.ad AS mad, musteri.soyad AS msoyad FROM randevu LEFT JOIN musteri ON randevu.musteri=musteri.id WHERE randevu.baslama='".$basla."' AND randevu.sube='".$_SESSION[ksube]."' AND randevu.bolum='".$listeboluml[id]."'"); 
     $uzmirandevul=mysql_fetch_array($uzmirandevu); 
     $yukseklik=(((($uzmirandevul[rbitis]-$uzmirandevul[rbaslama])/900)*26)-1); 
     echo "some data from databse"; 
     $basla=$uzmirandevul[rbitis]; 
    } 
} 
echo "</div>"; 
} 

MySQL структура:

`randevu` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
`baslama` int(10) unsigned NOT NULL, 
`bitis` int(10) unsigned NOT NULL, 
`musteri` int(10) unsigned NOT NULL, 
`personel` smallint(5) unsigned NOT NULL, 
`notum` varchar(512) COLLATE utf8_unicode_ci NOT NULL, 
`durum` char(2) COLLATE utf8_unicode_ci NOT NULL, 
`sube` smallint(4) unsigned NOT NULL, 
`bolum` smallint(4) unsigned NOT NULL, 
`hizmetler` varchar(256) COLLATE utf8_unicode_ci NOT NULL, 
`zaman` int(10) unsigned NOT NULL, 
`rgun` tinyint(2) NOT NULL, 
`ray` tinyint(2) NOT NULL, 
`ryil` smallint(4) NOT NULL, 
`guncelleme` int(10) NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; 
+0

Вы можете показать нам, как выглядит ваша структура базы данных? – sulmanpucit

+0

@sulmanpucit конечно – mandza

+0

'$ yukseklik = ($ uzmirandevul ['rbitis'] - $ uzmirandevul ['rbaslama'])/900 * 26-1;' – webbiedave

ответ

3

Потому что ваш код написан не на английском языке, это немного трудно для меня, чтобы понять это, но я советую вам немного почитать о N+1 problem. Вероятно, вы можете удалить второй запрос из цикла, чтобы сократить ваши SQL-запросы. Это называется нетерпеливой нагрузкой.

Вот пример:

SELECT * FROM authors // first query 

foreach ($authors as $author) { 
    SELECT * FROM books WHERE author_id = $author->id // second query 
} 

С 10 авторов, это работает просто отлично. Но у 100 авторов вы используете 101 запрос: 1 для получения списка авторов, а затем 1 для каждого автора. Другими словами, больше авторов означает больше запросов и, следовательно, более длительное время загрузки.

Вы можете ускорить процесс, путем удаления второго запроса из Еогеаспа-цикл:

SELECT * FROM authors // first query 

$author_ids = array(); 
foreach ($authors as $author) { 
    $author_ids[] = $author->id; // add author id to array 
} 

$author_ids = implode(',', $author_ids); // create a list of comma-seperated ids 

SELECT * FROM books WHERE author_id IN ($author_ids) // second query 

foreach ($authors as $author) { 
    // link books to authors 
} 

Таким образом, вы используете один запрос, чтобы получить все книги, а затем использовать PHP, чтобы связать книги справа авторы.

Это немного сложнее, но это уменьшает количество SQL-запросов до 2. Это, очевидно, все еще очень упрощенно, но оно должно дать вам представление о концепции.

+0

Спасибо, я посмотрю на это, и это то, что я хочу: удалить запрос из foreach, чтобы у меня был быстрый скрипт. Но, как я сказал, я не знаю, как это сделать. Теперь я ищу проблему N + 1 :) – mandza

+0

Я добавил пример. Это совсем не готово к использованию, но оно должно дать вам представление о концепции. –

+0

Большое спасибо, я попытаюсь реализовать его в своем коде. – mandza

 Смежные вопросы

  • Нет связанных вопросов^_^