MySQLã§ã©ã³ãã ã«N件åå¾ããæ¹æ³ã®ããã©ã¼ãã³ã¹æ¯è¼
こちらã¨åããããªæ¯è¼ãèªåã§ããã£ã¦ã¿ã¾ããã
ç§ã¯MySQLã«é¢ãã¦ãã¾ãæ·±ãç¥èãæã£ã¦ããªããããæ¤è¨¼ã®æ¹æ³ãè¨å®å¤ã®åé¡ãªã©ãããããããã¾ãããããã£ããã¨ããå¾åã¯åãããã¨æãã¾ãã
ã¾ããä»å使ç¨ãã¦ãããã¹ãç¨ç°å¢ã®ãã¼ã¸ã§ã³çã§ãã
- OS Fedora Core 7
- MySQL 5.0.45
- PHP 5.2.6
# ããå¤ãã»ã»ã»ã
ã¾ãããã¹ãã§ä½¿ç¨ãããã¼ãã«ã¯ä»¥ä¸ã®ãããªç°¡åãªãã®ã§ãã
ââââââ¬ââââââââ¬ââââ âãååãâãããåãããâãµã¤ãºâ ââââââ¼ââââââââ¼âââ⤠âï½ï½ããâï½ï½ï½ããããâãããâ主ãã¼ ââââââ¼ââââââââ¼âââ⤠âï½ï½ï½ï½ âï½ï½ï½ï½ï½ï½ï½âãï¼ï¼â ââââââ´ââââââââ´ââââ
ã¾ãä»åãã¹ããã6ã¤ã®æ¹æ³ãç°¡åã«èª¬æãã¾ãã
(1) RAND()åã追å ãã¦ã½ã¼ã
以ä¸ã®ãããªSQLã«ãªãã¾ãã
SELECT *, RAND() AS RANDOM_VALUE FROM test_table ORDER BY RANDOM_VALUE LIMIT 5
(2) ORDER BY RAND()
ãORDER BY RAND()ãã¨ORDER BYå¥ã«RAND()é¢æ°ã使ç¨ã§ãã¾ãã
SELECT * FROM test_table ORDER BY RAND() LIMIT 5
(3) ORDER BY RAND()æ¹
è¡ã®IDï¼ä¸»ãã¼ï¼ã ããã©ã³ãã ã«åå¾ãã¦ããããã¼ãã«æ¬ä½ã¨çµåãã¾ãã
SELECT * FROM test_table, (SELECT ID FROM test_table ORDER BY RAND() LIMIT 5) AS SUB1 WHERE test_table.ID = SUB1.ID
(4) ã©ã³ãã ã«ãªãã»ããã決å®
ã¬ã³ã¼ã件æ°ããã5ã¤ã®ãªãã»ããå¤ããããããã©ã³ãã ã«ï¼ããã°ã©ã ã§ï¼æ±ºå®ãã¦ãããããã5åã®ã¯ã¨ãªã§å¦çãã¾ãã
â»ãªãã»ããã®æ±ºå®ãPHPã§è¡ã£ã¦ãã¾ãã
<?php $stmt = $connection->prepare( "select count(*) as data_count from test_table" ); $stmt->execute(); $result = $stmt->fetch( PDO::FETCH_ASSOC ); $max = $result['data_count'] - 1; // ãªãã»ãããã©ã³ãã ã«5ã¤æ±ºå®ããã $offset_list = array(); while ( count( $offset_list ) < 5 ) { $rand_val = rand(0, $max); if ( in_array($rand_val, $offset_list)) { continue; } $offset_list[] = (int)$rand_val; } // çµæãåå¾ããã $ret = array(); $stmt = $connection->prepare( "select * from test_table limit :offset,1" ); foreach ($offset_list as $offset) { $stmt->bindParam(':offset', $offset, PDO::PARAM_INT); $stmt->execute(); $ret[] = $stmt->fetch( PDO::FETCH_ASSOC ); }
(5) IDãã©ã³ãã ã«5ã¤æå®ããï¼ãã®1ï¼
ãããããIDï¼ä¸»ãã¼ï¼ã®æå°å¤ã¨æ大å¤ãåå¾ãã¦ããããã®ç¯å²ã§ã©ã³ãã ãªIDãã1件ãã¤ã¬ã³ã¼ããåå¾ãã¾ãã
ãã ããIDãå®å
¨ãªé£çªã§ã¯ãªãã¦ç©ºãçªå·ãããå ´åãã¬ã³ã¼ããåå¾ã§ããªãå¯è½æ§ãããã¾ãããããèæ
®ãã¦æ£å¸¸ãªã¬ã³ã¼ãã5件åå¾ã§ããã¾ã§ç¹°ãè¿ãããã«ãã¦ããã¾ããçªå·ã®ç©ºãçã«ãã£ã¦ã¯åå¾å¤±æåæ°ãå¢ãã¦ãã¾ãã¾ããï¼ä»åã®ãã¹ããã¼ã¿ã§ã¯ã空ãçªå·ãããã¾ããï¼
<?php $stmt = $connection->prepare( "select min(id) as id_min, max(id) as id_max from test_table" ); $stmt->execute(); $result = $stmt->fetch( PDO::FETCH_ASSOC ); $min = $result['id_min']; $max = $result['id_max']; $ret = array(); $offset_list = array(); $stmt = $connection->prepare( "select * from test_table where id = :id" ); while ( count($ret) < 5 ) { while ( in_array($id = rand($min, $max), $offset_list) ) { } $offset_list[] = $id; $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); $record = $stmt->fetch( PDO::FETCH_ASSOC ); if ( count($record) < 1 ) { continue; } $ret[] = $record; }
2009/07/07 13:35追è¨
ãã³ã¡ã§id:sh2ãããã空æ¯ãã®åé¿æ¹æ³ããææããã ãã¾ããã
http://b.hatena.ne.jp/sh2/20090707#bookmark-14472787
(5)ã§ãselect * from test_table where id >= :id order by id limit 1ãã¨ããã¨ç©ºæ¯ãããªããªãã¾ãã 空ãçªç´å¾ã®IDã«ã¤ãã¦é¸æããã確çãå¢ãã¦ãã¾ããã©
ãªãã»ã©ããã£ãããéãã§ããã
ããã¯æããè¦ã¦ãIDã®ç©ºãçªå·ããããã¼ã¿ãä½ç¨®é¡ãç¨æãã¦ããã¡ãã¨è¨æ¸¬ãã¦ã¿ããã¨ããã§ãã
ãããããã¯ã¨ãªã®çºè¡åæ°ãå¿
ãæå®åæ°ã§ããã¾ãsh2ããã®æ¹æ³ãããªã¼ã«ã©ã¦ã³ãã«è¯å¥½ã ã¨æããã¾ããã»ã»ã»ã
ããã³ããããã¨ããããã¾ããï¼ï¼
(6) IDãã©ã³ãã ã«5ã¤æå®ããï¼ãã®2ï¼
(5)ã®æ¹æ³ã¨ä¼¼ã¦ãã¾ãããã¯ã¨ãªã®çºè¡åæ°ãæ¸ããããã«ãã©ã³ãã ãªIDãè¤æ°æ±ºå®ãã¦ãããWHEREå¥ã«INã使ç¨ãã¦1ã¤ã®SQLã§è¤æ°åå¾ãã¾ãã
ãã¡ããIDã®ç©ºãçªå·ãèæ
®ãã¦ãç®çã®ä»¶æ°ãããããå¤ãï¼ä»¥ä¸ã§ã¯10件ï¼ã®IDã渡ãã¦ãã¾ããï¼ãã®å ´åã¯çè«ä¸ç©ºãçªå·çã50%ã¾ã§è¨±å®¹ã§ãã¾ãï¼
ããã§æ¸¡ãIDã®æ°ãå¤ãããã»ã©ãããã©ã¼ãã³ã¹ãä½ä¸ãã¾ãã
ã¾ããçµæã®ã©ã³ãã æ§ã確ä¿ããããã«ãORDER BY RAND()ã§ããã«ã©ã³ãã ã«ä¸¦ã¹æ¿ãã¦ãã¾ãã
<?php $stmt = $connection->prepare( "select min(id) as id_min, max(id) as id_max from test_table" ); $stmt->execute(); $result = $stmt->fetch( PDO::FETCH_ASSOC ); $min = $result['id_min']; $max = $result['id_max']; $ret = array(); $offset_list = array(); while ( count($offset_list) < 10 ) { while ( in_array($id = rand($min, $max), $offset_list) ) { } $offset_list[] = $id; } $stmt = $connection->prepare( "select * from test_table where id in (" . implode(',',$offset_list) . ") order by rand() limit 5" ); $stmt->execute(); $rec = $stmt->fetchAll( PDO::FETCH_ASSOC );
é度æ¯è¼
ä¸è¨6ã¤ã®æ¹æ³ï¼ãã¹ã¦PHPããå®è¡ã5件ã®ã¬ã³ã¼ããå¤æ°ã«æ ¼ç´ããã¾ã§ï¼ãã以ä¸ã®2ã¤ã®å ´åã«ã¤ãã¦å®è¡æéã®è¨æ¸¬ãè¡ãã¾ããã
- MyISAMã¨InnoDB
- ãã¼ãã«ã®ã¬ã³ã¼ãæ°1ä¸ä»¶ã¨100ä¸ä»¶
- ãããã5åå®è¡ããåå®è¡æéã®å¹³åãã¨ã£ã¦ãã¾ã
ã¾ãããã¼ã¿éã1ä¸ä»¶ã®å ´åã¯ãã©ã®æ¹æ³ã§ã0.1ç§ä»¥ä¸ã®å®è¡æéã§ãã
ãã ããå¦çãããã¼ãã«ã«ãã£ã¼ã«ãããããããããªã©ããã¼ãã«å
¨ä½ã®ãã¼ã¿éãå¤ãå ´åã(1)ã¨(2)ã®æ¹æ³ã§ã¯ãã¼ã¿éã«æ¯ä¾ãã¦ããã©ã¼ãã³ã¹ãå£åãã¾ããããã¯ãRAND()åã追å ããããORDER BY RAND()ã使ç¨ããã¨ãå¦ç対象ã®ãã¼ãã«ã®ä½¿ç¨ãããã£ã¼ã«ããããã³RAND()ã®åã§ä¸æãã¼ãã«ãä½æããããã®ä¸æãã¼ãã«ã§ã½ã¼ããè¡ãããããã§ããä¸æãã¼ãã«ãã®ãã®ã®ä½æã¨ä¸¦ã¹æ¿ãã«ãããæéãããã³ã¡ã¢ãªãå§è¿«ãããã¨ã«ãããªã¼ãã¼ããããªã©ãããã¤ãã®è¦å ã§ããã©ã¼ãã³ã¹ãå£åããããã§ãã
ãããã£ã¦ãORDER BY RAND()ã使ç¨ããå ´åã§ããå°ãªãã¨ã(3)ã®æ¹æ³ã®ããã«ä¸»ãã¼ã ãã§ã©ã³ãã ã¬ã³ã¼ããåå¾ããããã«ããæ¹ãããã¨æããã¾ãã
MyISAMã¨InnoDBã®æ¯è¼ã§ã¯ã(4)ã®æ¹æ³ã§ããªãå·®ãåºã¦ãã¾ããããã¯ãMyISAMã®å ´åã¯SELECT COUNT(*)ããã¼ãã«ã®ã¬ã³ã¼ãæ°ã«é¢ä¿ãªãä¸ç¬ã§åå¾ã§ããã®ã«å¯¾ãã¦ãInnoDBã§ã¯ã¬ã³ã¼ãæ°ã«ä¾åããå®è¡æéãããã£ã¦ãã¾ãããã§ãã
InnoDBã®ãã®åé¡ãåé¿ããããã«ãこちらã®ããã«ã¬ã³ã¼ãæ°ãå¥ãã¼ãã«ã«ãã£ãã·ã¥ãã¦ãããããªå¯¾çãããã¾ãã
ãã ãã¬ã³ã¼ãæ°ã100ä¸ä»¶ã¯ã©ã¹ã«ãªãã¨ãMyISAMã§ãå¦çæéã1ç§ãè¶
ãã¾ãã®ã§ãã¦ã§ããã¼ã¸ã§ãªã¢ã«ã¿ã¤ã ã«çµæã表示ãããããªå ´åã«ã¯ä½¿ç¨ã§ããªãã§ãããã
ï¼OFFSETã«æ¯ä¾ãã¦å®è¡æéãé·ããªãã¾ããï¼
æå¾ã®(5)ã¨(6)ã®æ¹æ³ã§ãããã¬ã³ã¼ãã主ãã¼ããåãåºãã®ã§å§åçã«é«éã§ãã1ä¸ä»¶ã®å ´åã§ãå®è¡æéã1æ¡éãã¾ããã¬ã³ã¼ãæ°ã100ä¸ä»¶ã«ãªã£ã¦ããããã©ã¼ãã³ã¹ãå£åãã¾ãããï¼å®éã¯ãã¤ã³ããã¯ã¹ãã¡ã¢ãªã«åã¾ã£ã¦ããã®ãã©ãããã¨ããåå¥ã®ç¶æ³ã§å£åå ·åã¯å¤åããã¨æãã¾ããï¼
ãããã(6)ã®æ¹æ³ãåä½ã§ç¨ããã®ã¯ãã¯ããªã¹ã¯ã大ããã§ããããéç¨ä¸ã«IDã®ç©ºãçªå·ã®ç¶æ³ãå¤åãã¦ã100件ã©ã³ãã ãªIDãä¸ãã¦ã¿ããã©ããã®ä¸ã«å®éã«åå¨ããã¬ã³ã¼ãã3件ãããªãã£ããã¨ãªãå¯è½æ§ãèãããã¾ããããã«ä¿éºãããã¦ããå¿ è¦ãåºã¦ããã®ã§ããããããªãã¨ã確å®ã«5件åå¾ã§ãã(5)ã®æ¹æ³ãç¡é£ãªã®ããããã¾ããã
P.S.
MySQLã«è©³ããå人ã®Fakeãããããã£ã¨ãããæ¹æ³ãè¦ã¤ãã¦ãããã¨æå¾
ãã¦ãã¾ãã»ã»ã»ã»ï½