разбивка по страницам

antoneskoV

Новичок
Есть код разбивки новостей по странично. На страницы 7 новостей. Проблема в том что если на страницы нету новостей равного числу 7, то добавляется дополнительная пустая страничка. В итоге все нормально выводит но добавляет пустую страницу в конце.
Вот кусок кода. Причина заключается в том что не правильно подсчитываться значения $disp_to.

PHP:
//Визначаю кількість сторінок зі знайденими результатами $total_pages
	$arts_per_page=10;
	$i= $total_pages1%$arts_per_page;
	if ($i==0) {$total_pages=$total_pages1/$arts_per_page;} else {$total_pages=(($total_pages1-$i)/$arts_per_page)+1;}
	$disp_from=(ceil($page1/$arts_per_page)-1)*$arts_per_page+1;//Мне кажется причина кроется в неправильном округлений

	$disp_to=$disp_from+$arts_per_page-1;

	if ($disp_to>$total_pages1) {$disp_to=$total_pages1;} //По яку статтю
И цикл вывода
PHP:
for ($i=$disp_from; $i<=$disp_to; $i++) 
  {
  if ($page1==$i)
   {echo "<span class=\"str_link\">";
   echo "".$i."";
   echo "</span>";}
   else
   {echo "<span class=\"str_links\">";
   echo '<a href="'.$filereferer.$param.'page='.$i.'">'.$i.'</a>';
   echo "</span>";
   }
Пробовал менять функцию округления! Но в итоге ничего не получилось! :(
 

antoneskoV

Новичок
Попробовал как посоветовал! Проблема осталась!
PHP:
$disp_from = floor(($page1-1)/ $arts_per_page)+1;
 

Semen

Семён
я использую такую функцию
PHP:
function pagination($page, $limit, $count){
$pagination = '';
$i = 1;
	if ( $count > $limit ){
		while(1 <= $count){
			$count -= $limit;
			$className = ($i == $page) ? 'page' : 'pageLink' ;
			$pagination .= '<span id="page'.$i.'" class="'.$className.'">'.$i.'</span> ';
			$i++;
		}
	}
return $pagination;
}
 

Активист

Активист
Команда форума
Статья морально устарела, простого упоминания
> если версия mysql больше 4.0
мало.

$q="SELECT count(*) FROM table";
давно пора выпилить вообще из статьи.

и использовать что-нибудь подобное
PHP:
$this->core->mysql->query("SELECT SQL_CALC_FOUND_ROWS `title`, `date` FROM `news` WHERE `lang` = '".$this->escape($this->core->currentLanguage)."' ORDER BY `date` ");

while ($result = $this->core->mysql->next_row_assoc()) {
$this->data['items'][] = $result;
}
$this->core->mysql->query("SELECT FOUND_ROWS() AS `rows`", true);
$rows = $this->core->mysql->field('rows');
 

Активист

Активист
Команда форума
zerkms

Та статья, от 2007 года, тоже моральна устарела, делал тесты по той статье, у меня ситуация полностью обратная получилась

Код:
mysql> select SQL_NO_CACHE count(*) from `count_test` WHERE b = 555 ORDER BY c LIMIT 5;
+----------+
| count(*) |
+----------+
|     1018 |
+----------+
1 row in set (0.27 sec)

mysql> SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS * FROM count_test WHERE b = 555 ORDER BY c LIMIT 5;
+-------+-----+---+----------------------------------+
| a     | b   | c | d                                |
+-------+-----+---+----------------------------------+
|  6556 | 555 | 0 | 6fae4e7975cfb72a356e6a8682456c6e |
| 10556 | 555 | 0 | a62a015d7642877c86d50c266a38b636 |
| 14556 | 555 | 0 | 3b745f046957f6b3ea1b037370023dc4 |
| 39556 | 555 | 0 | f47b47a611df8ce65ef10b826ed1ad2e |
| 43556 | 555 | 0 | 790d8fa56e05ff05080e6e66fae0272a |
+-------+-----+---+----------------------------------+
5 rows in set (0.16 sec)
 

zerkms

TDD infected
Команда форума
Активист
Как запрос с LIMIT 5 может выдать 1018?
Зачем для запроса с COUNT() сортировка?

Плюс после первого запроса данные уже прогретые.
 

Активист

Активист
Команда форума
Вот пример запросов из статьи.
Код:
mysql> SELECT SQL_NO_CACHE count(*) FROM count_test WHERE b = 666;
+----------+
| count(*) |
+----------+
|     1520 |
+----------+
1 row in set (0.81 sec)

mysql> SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS * FROM count_test WHERE b = 666 ORDER BY c LIMIT 5;
+-------+-----+---+----------------------------------+
| a     | b   | c | d                                |
+-------+-----+---+----------------------------------+
| 19667 | 666 | 0 | 2d40f027dc7db2e6860f88994ac7a265 |
| 20667 | 666 | 0 | 6ac37313e074d4fa4c73335747f35fa1 |
| 34667 | 666 | 0 | 8a45da3f21ea12d7948abeaf346c5bd1 |
| 41667 | 666 | 0 | 3a7c2a3144427d8921928f3ab3112bf7 |
| 44667 | 666 | 0 | aae92066b9e2a57287b442383d7b88b6 |
+-------+-----+---+----------------------------------+
5 rows in set (0.39 sec)

mysql>
> Как запрос с LIMIT 5 может выдать 1018?
Не знаю, я копи паст делаю :)

Код:
mysql> SELECT VERSION();
+-------------------+
| VERSION()         |
+-------------------+
| 5.0.51a-24+lenny4 |
+-------------------+
1 row in set (0.00 sec)

mysql>

Про какие там 20-100 секунд говориться, не знаю, сервер девелоперский, селерон 1.8 с 512 мб озу.
 

zerkms

TDD infected
Команда форума
Не верю. Как-то у тебя оба запроса слишком дохера долго выполняются.

Сколько данных? SHOW CREATE TABLE?
 

Активист

Активист
Команда форума
Сервер загружен, ну проведи тесты сам, увидишь там 20-100 секунд, расскажи, я на собственном опыте могу сказать - статья та, про то что SQL_CALC_FOUND_ROWS потеряла актуальность.
 

Активист

Активист
Команда форума
linux-debian-1:~# uname -a
Linux linux-debian-1.local 2.6.26-2-686 #1 SMP Thu Nov 25 01:53:57 UTC 2010 i686 GNU/Linux
linux-debian-1:~# uptime
12:21:26 up 3 days, 3:31, 2 users, load average: 3.06, 3.05, 2.86
linux-debian-1:~#
 

korchasa

LIMB infected
Активист
1. SQL_CALC_FOUND_ROWS может быть быстрее двух запросов, только если нет индекса на b
2. При тестировании на загруженном железе нежно делать много замеров
3. При тестировании на la ~ числу процессоров, результаты получаются оооочень зависимыми от фазы луны
 

Активист

Активист
Команда форума
korchasa
1. БД создана такая же как в статье
http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

Код:
mysql> SELECT SQL_NO_CACHE count(*) FROM count_test WHERE b = 666;
+----------+
| count(*) |
+----------+
|     2783 |
+----------+
1 row in set (0.00 sec)

mysql> SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS * FROM count_test WHERE b = 666 ORDER BY c LIMIT 5;
+-------+-----+---+----------------------------------+
| a     | b   | c | d                                |
+-------+-----+---+----------------------------------+
| 19667 | 666 | 0 | 2d40f027dc7db2e6860f88994ac7a265 |
| 20667 | 666 | 0 | 6ac37313e074d4fa4c73335747f35fa1 |
| 34667 | 666 | 0 | 8a45da3f21ea12d7948abeaf346c5bd1 |
| 41667 | 666 | 0 | 3a7c2a3144427d8921928f3ab3112bf7 |
| 44667 | 666 | 0 | aae92066b9e2a57287b442383d7b88b6 |
+-------+-----+---+----------------------------------+
5 rows in set (0.01 sec)

mysql> show create table `count_test`;
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                                                                                                                                                            |
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| count_test | CREATE TABLE `count_test` (
  `a` int(10) NOT NULL auto_increment,
  `b` int(10) NOT NULL,
  `c` int(10) NOT NULL,
  `d` varchar(32) NOT NULL,
  PRIMARY KEY  (`a`),
  KEY `bc` (`b`,`c`)
) ENGINE=MyISAM AUTO_INCREMENT=2892002 DEFAULT CHARSET=cp1251 |
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.24 sec)

mysql>
2, 3 - моя основная задача - опровергнуть указанное в статье 20-100 sec to execute uncached, а что лучше - COUNT() или не COUNT(), я выбрал SQL_CALC_FOUND_ROWS, поскольку результаты практически идентичны.

Делал я это, кстати, еще месяц назад где-то, после прочтения как раз этой статьи, вот сейчас еще раз SQL-ники показал.
 

zerkms

TDD infected
Команда форума
Активист
По твоей последней ссылке почитай мой коммент и 2 ответа на него )))
 

Активист

Активист
Команда форума
Щас, еще немного, я забью до 10М записей в БД и выложу сюда SQL, тесты на 4М показывают как минимум идентичные скорости селекта, сделаю 10M записей и посмотрю, оставив тяжёлые сервисы.
 

Вурдалак

Продвинутый новичок
SQL_CALC_FOUND_ROWS — говно уже хотя бы потому, что нельзя вычислить кол-во страниц до запроса. Это необходимо, например, чтобы перебрасывать на последнюю страницу, если передан номер страницы больше максимального. Человек сохранил ссылку на последнюю страницу, пришли модераторы и почистили пару страниц. Куда попадает человек?
 

Активист

Активист
Команда форума
Вот такой результат, но 20-100 сек тут нет, 10 миллионов записей. Выводы делайте сами.

Код:
linux-debian-1:~# uptime
 19:25:22 up 3 days, 10:35,  1 user,  load average: 0.19, 0.20, 0.12
linux-debian-1:~# /etc/init.d/mysql stop
Stopping MySQL database server: mysqld^[[A.
linux-debian-1:~# /etc/init.d/mysql start
Starting MySQL database server: mysqld.
Checking for corrupt, not cleanly closed and upgrade needing tables..
linux-debian-1:~# mysql -u su1234
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 67
Server version: 5.0.51a-24+lenny4 (Debian)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show create table `count_test`\G
*************************** 1. row ***************************
       Table: count_test
Create Table: CREATE TABLE `count_test` (
  `a` int(10) NOT NULL auto_increment,
  `b` int(10) NOT NULL,
  `c` int(10) NOT NULL,
  `d` varchar(32) NOT NULL,
  PRIMARY KEY  (`a`),
  KEY `bc` (`b`,`c`)
) ENGINE=MyISAM AUTO_INCREMENT=10000001 DEFAULT CHARSET=cp1251
1 row in set (0.01 sec)

mysql> SELECT SQL_NO_CACHE * FROM count_test WHERE b = 666 ORDER BY c LIMIT 5;
+-------+-----+---+----------------------------------+
| a     | b   | c | d                                |
+-------+-----+---+----------------------------------+
| 19667 | 666 | 0 | 2d40f027dc7db2e6860f88994ac7a265 |
| 20667 | 666 | 0 | 6ac37313e074d4fa4c73335747f35fa1 |
| 34667 | 666 | 0 | 8a45da3f21ea12d7948abeaf346c5bd1 |
| 41667 | 666 | 0 | 3a7c2a3144427d8921928f3ab3112bf7 |
| 44667 | 666 | 0 | aae92066b9e2a57287b442383d7b88b6 |
+-------+-----+---+----------------------------------+
5 rows in set (0.73 sec)

mysql> SELECT SQL_NO_CACHE * FROM count_test WHERE b = 666 ORDER BY c LIMIT 5;
+-------+-----+---+----------------------------------+
| a     | b   | c | d                                |
+-------+-----+---+----------------------------------+
| 19667 | 666 | 0 | 2d40f027dc7db2e6860f88994ac7a265 |
| 20667 | 666 | 0 | 6ac37313e074d4fa4c73335747f35fa1 |
| 34667 | 666 | 0 | 8a45da3f21ea12d7948abeaf346c5bd1 |
| 41667 | 666 | 0 | 3a7c2a3144427d8921928f3ab3112bf7 |
| 44667 | 666 | 0 | aae92066b9e2a57287b442383d7b88b6 |
+-------+-----+---+----------------------------------+
5 rows in set (0.00 sec)

mysql> SELECT SQL_NO_CACHE count(*) FROM count_test WHERE b = 666;
+----------+
| count(*) |
+----------+
|    10000 |
+----------+
1 row in set (0.01 sec)

mysql> SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS * FROM count_test WHERE b = 666 ORDER BY c LIMIT 5;
+-------+-----+---+----------------------------------+
| a     | b   | c | d                                |
+-------+-----+---+----------------------------------+
| 19667 | 666 | 0 | 2d40f027dc7db2e6860f88994ac7a265 |
| 20667 | 666 | 0 | 6ac37313e074d4fa4c73335747f35fa1 |
| 34667 | 666 | 0 | 8a45da3f21ea12d7948abeaf346c5bd1 |
| 41667 | 666 | 0 | 3a7c2a3144427d8921928f3ab3112bf7 |
| 44667 | 666 | 0 | aae92066b9e2a57287b442383d7b88b6 |
+-------+-----+---+----------------------------------+
5 rows in set (1.12 sec)

mysql> SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS * FROM count_test WHERE b = 666 ORDER BY c LIMIT 5;
+-------+-----+---+----------------------------------+
| a     | b   | c | d                                |
+-------+-----+---+----------------------------------+
| 19667 | 666 | 0 | 2d40f027dc7db2e6860f88994ac7a265 |
| 20667 | 666 | 0 | 6ac37313e074d4fa4c73335747f35fa1 |
| 34667 | 666 | 0 | 8a45da3f21ea12d7948abeaf346c5bd1 |
| 41667 | 666 | 0 | 3a7c2a3144427d8921928f3ab3112bf7 |
| 44667 | 666 | 0 | aae92066b9e2a57287b442383d7b88b6 |
+-------+-----+---+----------------------------------+
5 rows in set (0.02 sec)



mysql> SELECT FOUND_ROWS();
+--------------+
| FOUND_ROWS() |
+--------------+
|        10000 |
+--------------+
1 row in set (0.00 sec)

linux-debian-1:~# cd /var/lib/mysql/test
linux-debian-1:/var/lib/mysql/test# ls -lah | grep count
-rw-rw----   1 mysql mysql 8,5K Дек  3 20:18 count_test.frm
-rw-rw----   1 mysql mysql 494M Дек 13 19:33 count_test.MYD
-rw-rw----   1 mysql mysql 282M Дек 13 19:39 count_test.MYI
linux-debian-1:/var/lib/mysql/test# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 15
model           : 6
model name      : Intel(R) Celeron(R) D CPU 3.06GHz
stepping        : 4
cpu MHz         : 3059.138
cache size      : 512 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 6
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc up pebs bts pni monitor ds_cpl cid cx16 xtpr lahf_lm
bogomips        : 6125.09
clflush size    : 64
power management:

linux-debian-1:/var/lib/mysql/test# cat /proc/meminfo
MemTotal:       507148 kB
MemFree:         59768 kB
Buffers:          6900 kB
Cached:         322212 kB
SwapCached:          0 kB
Active:         322784 kB
Inactive:        88700 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:       507148 kB
LowFree:         59768 kB
SwapTotal:     1477940 kB
SwapFree:      1477272 kB
Dirty:             716 kB
Writeback:           0 kB
AnonPages:       82392 kB
Mapped:          17492 kB
Slab:            28864 kB
SReclaimable:    14260 kB
SUnreclaim:      14604 kB
PageTables:       1144 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
WritebackTmp:        0 kB
CommitLimit:   1731512 kB
Committed_AS:   712716 kB
VmallocTotal:   516088 kB
VmallocUsed:      4228 kB
VmallocChunk:   511800 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
HugePages_Surp:      0
Hugepagesize:     4096 kB
linux-debian-1:/var/lib/mysql/test#
Celeron
 
Сверху