Mysql
 sql >> база данни >  >> RDS >> Mysql

Оптимална заявка за извличане на кумулативна сума в MySQL

Можете да използвате променлива - това е много по-бързо от всяко присъединяване:

ИЗБЕРЕТЕ идентификатор, размер, @total :=@total + size AS cumulativeSize,FROM таблица, (SELECT @total:=0) AS t; 

Ето един бърз тестов случай на Pentium III със 128MB RAM, работещ с Debian 5.0:

Създайте таблицата:

ПРОПУСКАНЕ НА ТАБЛИЦА, АКО СЪЩЕСТВУВА `table1`;СЪЗДАВАНЕ НА ТАБЛИЦА `table1` ( `id` int(11) НЕ NULL auto_increment, `size` int(11) НЕ NULL, ПЪРВЕН КЛЮЧ (`id`)) ДВИГАТЕЛ =InnoDB; 

Попълнете с 20 000 произволни числа:

DELIMITER //ПРОЦЕДУРА ИЗПУСКАНЕ, АКО СЪЩЕСТВУВА autofill//СЪЗДАВАНЕ НА ПРОЦЕДУРА autofill()ЗАПОЧВА ОБЯВЯВАНЕ i INT DEFAULT 0; ДОКАТО i <20000 ДА ВМЕСЕТЕ В таблица1 (размер) СТОИ (FLOOR((RAND() * 1000))); SET i =i + 1; END WHILE;END;//DELIMITER;ИЗВИКВАНЕ на автоматично попълване(); 

Проверете броя на редовете:

ИЗБЕРЕТЕ БРОЙ(*) ОТ таблица1;+----------+| БРОЙ(*) |+---------+| 20000 |+----------+ 

Изпълнете кумулативната обща заявка:

ИЗБЕРЕТЕ идентификатор, размер, @total :=@total + size AS cumulativeSizeFROM table1, (SELECT @total:=0) AS t;+-------+------+ ----------------+| ID | размер | кумулативен размер |+-------+-----+----------------+| 1 | 226 | 226 || 2 | 869 | 1095 || 3 | 668 | 1763 || 4 | 733 | 2496 |...| 19997 | 966 | 10004741 || 19998 | 522 | 10005263 || 19999 | 713 | 10005976 || 20000 | 0 | 10005976 |+-------+-----+----------------+20000 реда в комплект (0,07 сек) 

АКТУАЛИЗИРАНЕ

Бях пропуснал групирането по groupId в оригиналния въпрос и това със сигурност направи нещата малко по-трудни. След това написах решение, което използва временна таблица, но не ми хареса — беше разхвърляно и прекалено сложно. Отидох и направих още малко проучване и измислих нещо много по-просто и по-бързо.

Не мога да претендирам цялата заслуга за това — всъщност почти не мога да претендирам за такава, тъй като това е просто модифицирана версия на Емулиране на номер на ред от Общи заявки за MySQL .

Това е красиво просто, елегантно и много бързо:

ИЗБЕРЕТЕ fileInfoId, groupId, име, размер, cumulativeSizeFROM ( SELECT fileInfoId, groupId, име, размер, @cs :=IF(@prev_groupId =groupId, @cs+size, size) AS cumulativeSize, @prev_groupId :=groupId AS prev_groupId FROM fileInfo, (SELECT @prev_groupId:=0, @cs:=0) AS vars ORDER BY groupId) AS tmp; 

Можете да премахнете външния SELECT ... AS tmp ако нямате нищо против prev_groupID колона се връща. Открих, че работи незначително по-бързо без него.

Ето един прост тестов случай:

ВЪВЕТЕ ВЪВ `fileInfo` СТОЙНОСТИ( 1, 3, 'name0', '10'),( 5, 3, 'name1', '10'),( 7, 3, 'name2', ' 10'),( 8, 1, 'име3', '10'),( 9, 1, 'име4', '10'), (10, 2, 'име5', '10'), (12, 4 , 'name6', '10'),(20, 4, 'name7', '10'),(21, 4, 'name8', '10'),(25, 5, 'name9', '10' );ИЗБЕРЕТЕ fileInfoId, groupId, име, размер, cumulativeSizeFROM ( SELECT fileInfoId, groupId, име, размер, @cs :=IF(@prev_groupId =groupId, @cs+size, size) AS cumulativeSize, @prev_groupId :=groupId AS prev_ FROM fileInfo, (SELECT @prev_groupId :=0, @cs :=0) AS vars ПОРЪЧАЙТЕ ПО groupId) КАТО tmp;+------------+---------+ -------+-----+----------------+| fileInfoId | groupId | име | размер | кумулативен размер |+------------+--------+-------+-----+-------- -------+| 8 | 1 | име3 | 10 | 10 || 9 | 1 | име4 | 10 | 20 || 10 | 2 | име5 | 10 | 10 || 1 | 3 | име0 | 10 | 10 || 5 | 3 | име1 | 10 | 20 || 7 | 3 | име2 | 10 | 30 || 12 | 4 | име6 | 10 | 10 || 20 | 4 | име7 | 10 | 20 || 21 | 4 | име8 | 10 | 30 || 25 | 5 | име9 | 10 | 10 |+------------+--------+-------+------+--------- -------+ 

Ето извадка от последните няколко реда от таблица с 20 000 реда:

<предварителен код>| 19481 | 248 | 8CSLJX22RCO | 1037469 | 51270389 || 19486 | 248 | 1IYGJ1UVCQE | 937150 | 52207539 || 19817 | 248 | 3FBU3EUSE1G | 616614 | 52824153 || 19871 | 248 | 4N19QB7PYT | 153031 | 52977184 || 132 | 249 | 3NP9UGMTRTD | 828073 | 828073 || 275 | 249 | 86RJM39K72K | 860323 | 1688396 || 802 | 249 | 16Z9XADLBFI | 623030 | 2311426 |...| 19661 | 249 | ADZXKQUI0O3 | 837213 | 39856277 || 19870 | 249 | 9AVRTI3QK6I | 331342 | 40187619 || 19972 | 249 | 1MTAEE3LLEM | 1027714 | 41215333 |+------------+--------+------------+---------+ ----------------+20000 реда в комплект (0,31 сек)

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mysql + php със специални знаци като '(Апостроф) и (Кавичка)

  2. Премахване на връщане на карета в Mysql DB

  3. MySQL:Вмъкване в множество таблици в една и съща заявка с BEGIN&COMMIT

  4. Как да инсталирате WordPress:сървърният софтуер

  5. Грешка при анализа:синтактична грешка, неочаквана (T_VARIABLE)