ãŸããå žåçãªããžãã¹èŠä»¶ã®æŠèŠã説æããããããå ¥åæ¡ä»¶ãå°ãåºããŸãããªã¹ãïŒãŠãŒã¶ãŒãååããã©ã³ã¶ã¯ã·ã§ã³ïŒããããŒã¿ãéžæããŸãã ãµã³ããªã³ã°ã¯ã1ã€ä»¥äžã®ãã£ã«ã¿ãŒãšããã€ãã®ãœãŒãåºæºã䜿çšããŠå®è¡ãããŸãã ãã¹ãŠã®ããŒã¿ãããŒãããå¿ èŠãããJavaScriptã®ã€ã³ã¿ã©ã¯ãã£ãã°ãªãããªã©ã®çŽç²ãªã¯ã©ã€ã¢ã³ããœãªã¥ãŒã·ã§ã³ã®åé¡ã¯ããã§ã¯èæ ®ãããŸãããããµãŒããŒã§ããŒãžããŒã·ã§ã³ãè¡ãããããç©ãããªãªãã·ã§ã³ã«çŠç¹ãåœãŠãŸãã
ããã¯äŒçµ±çã«ã©ã®ããã«è¡ãããŸããïŒ ã¢ããªã±ãŒã·ã§ã³å±€ã¯ããã£ã«ã¿ãŒå€ãå¿ èŠãªæåã®ã¬ã³ãŒãã®ã€ã³ããã¯ã¹ãããã³ããŒãžãããã®å¿ èŠãªã¬ã³ãŒãæ°ãããã¯ãšã³ãã«æž¡ããŸãã å¿çãšããŠãããŒã¿ããŒã¹ã¯ãµã³ãã«å šäœã«ãã£ã«ã¿ãŒãé©çšãããã£ã«ã¿ãŒåŠçããããµãã»ããå šäœãé 眮ããMããM + N-1ã®ã¬ã³ãŒããè¿ããŸãã ãããŸãã¯ãã®éçºè ããã³/ãŸãã¯ãã®ãŸãã¯ãã®ããŒãžã§ã³ã®RDBMSããããè¡ãæ¹æ³ã¯ä»ã§ã¯éèŠã§ã¯ãããŸãã-éèŠãªããšã¯ã䜿çšãããŠããã¡ãœããïŒMS SQL 2000ã®äžæããŒãã«ã2005幎ã®ROW_NUMBER OVERïŒïŒ 2008ããŸãã¯2011幎ã®TOP / OFFSETïŒããã£ã«ã¿ãŒãããé åºä»ãã»ããããçªå·ä»ããµãã»ãããçºè¡ããå¿ èŠã¯ãå¿ ç¶çã«ãã£ã«ã¿ãŒãšãœãŒãåŸã«äžéçµæå šäœã®ãããã解ãããšãæå³ããŸãã ãã®ã¢ã³ã¯ã€ã³ããã©ãã§å®è¡ããããã¯éèŠã§ã¯ãããŸãã-ããŒã¿ã¹ããŒã¹äžãŸãã¯ã€ã³ããã¯ã¹ãã£ãŒã«ãäžã§ïŒããšãã°ãå®å šãªã€ã³ããã¯ã¹ã«ãã¬ããžãŸãã¯INCLUDEDåã䜿çšããå ŽåïŒ-ãã®éãã¯ååãå€æŽããŸããã
ãã£ã«ã¿ãªã³ã°ä¿æ°ãäœãããã£ã«ã¿ãŒãåŽåéçŽåïŒãã«ããã¹ãæ€çŽ¢ãªã©ïŒã§ããå Žåãç¹ã«éžæã®æåŸã®ããŒãžã«è¿ã¥ããšããã®æ¹æ³ã®å¹çãéåžžã«äœããªãããšã¯æããã§ãã ãŸãããã£ã«ã¿ãŒããã©ã¡ããªãã¯ã§ïŒããšãã°ããŠãŒã¶ãŒããŒãã«ã®ãŠãŒã¶ãŒã®ã¿ã€ãã«å¿ããŠïŒãç¹å¥ã«äœæãããã€ã³ããã¯ã¹ã«åŸã£ãŠåäœããå Žåã§ããæåŸã®ããŒãžã®ãã¹ãŠã®ãªã¯ãšã¹ãã«å¯ŸããŠãµãŒããŒã®åªåã®ã»ãŒ100ïŒ ãæšãŠãããšã«ãããå®éã«ã¯RDBMSèªäœã®éçã«èª å®ãªåæ ãçããŸãã玡瞟ã
å®éã®ã¯ã©ã€ã¢ã³ã/ãµãŒããŒã¢ããªã±ãŒã·ã§ã³ã§ã¯ãç¶æ³ãè€éã«ããããã€ãã®ç¹ããŸã ãããŸãã
aïŒããŒãžããŒã·ã§ã³ã䜿çšããŠããŒãžãæ£ããã¬ã³ããªã³ã°ããããã«ïŒçšèªã«ã€ããŠè¬çœªããŸãïŒãã¢ããªã±ãŒã·ã§ã³ã¬ã€ã€ãŒã¯ãã£ã«ã¿ãŒãééããã¬ã³ãŒãã®ç·æ°ãç¥ãå¿ èŠããããŸã-Nã§é€ç®ããïŒæãããªæ³šæãæã£ãŠïŒåãäžããããã«å¿ èŠãªããŒãžæ°ãååŸããŸãããã²ãŒã·ã§ã³ã¡ãã¥ãŒã ãããå®çŸããã«ã¯ãããã¯ãšã³ãã¯å®éã«åããŒãžã®éžæäžã«æ€çŽ¢ã¯ãšãªã2åå®è¡ããå¿ èŠããããŸã-åãæšãŠãããããŒãžã§ã³ã§åããŠ-åã«éžæ... COUNTïŒ1ïŒ... WHEREãéšåéžæãšäžŠã¹æ¿ããªãã2çªç®-ãã§ã«å®å šã«ãç®çã®ã»ãããéžæããŠã¬ã³ãŒãã ãŸãã¯ããã£ã«ã¿ãŒåŠçãããåºåã«åããŠã¢ã¯ã»ã¹ãããšãã«COUNTãå®è¡ãããã®å€ãèŠããŠãããŠãã ããã
bïŒãŠãŒã¶ãŒãããŒãžãããã²ãŒãããŠãããšãã«ãæ°ããã¬ã³ãŒããããŒã¿ããŒã¹ã«è¡šç€ºããïŒãŸãã¯æ¢åã®ã¬ã³ãŒããåé€ããïŒããã£ã«ã¿ãŒæ¡ä»¶ã«è©²åœããå Žåãããã²ãŒã·ã§ã³ã¯ç§»åãããŠãŒã¶ãŒã¯1ã€ä»¥äžã®ã¬ã³ãŒããã¹ããããŸãã¯å衚瀺ã§ããŸãã
cïŒäžè¬çã«èšãã°ãããŒã¿ããŒã¹ã¯ãACIDã®ååã«åºã¥ããŠæ§ç¯ããããããªãã¯ã·ã¹ãã ã§æå°ã®ã¹ã±ãŒã©ãã«ãªã³ã¯ã§ãã ãããã£ãŠãäžåºŠä¿¡é Œã§ãããã¹ãŠã®ããŒã¿ãåæã«æã€ããã«ã·ã¹ãã ãèšèšããå Žåãæåã«ããŒã¿ããŒã¹ãªãœãŒã¹ãç¯çŽããç°¡åã«ã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã«é åžã§ãããã¹ãŠã®ãã®ãä¿åããããšã¯çŽæ¥æå³ããããŸãã
å žåçãªããŒãžããŒã·ã§ã³æäœã¢ã«ãŽãªãºã ã¯ãCã®ãããªã³ãŒãã§ã¯æ¬¡ã®ããã«ãªããŸãïŒDBãã¬ãã£ãã¯ã¹ãæã€é¢æ°ã¯ããŒã¿ããŒã¹ã§å®è¡ãããŸãïŒã
while (1) { create_filter(FormData, &F, &S); // F S // FormData DB_get_count(F, &C); // - while (1) // , F S ( ) { DB_get_records(F, N, M, S); // N , M F S if (SORT_OR_FILTER_CHANGED == do_navigation(FormData, C, &N, &M, &S)) // { break; // - } } }
ããã§ã¯ãæåã®è¡šç€ºãšãã®åŸã®åããã²ãŒã·ã§ã³ã§DB_get_recordsã®ã¬ã³ãŒãã®åãã£ã«ã¿ãªã³ã°ãåãé€ããŠãæ¹åãè©Šã¿ãŸãããã ãããè¡ãã«ã¯ããã£ã«ã¿ãŒã«äžèŽããã¬ã³ãŒãæ°ã®éžæãç §äŒãã代ããã«ãæ£ããé åºã§ãœãŒããããäž»ããŒã®é åå šäœãéžæããŸãã ããã§ã¯ãã¬ã³ãŒãã®äž»ããŒãã³ã³ãã¯ãïŒããšãã°ãintãŸãã¯bigintïŒã§ãããšæ³å®ãããŠãããæå°éã®ãã£ã«ã¿ãªã³ã°ã§ãµã³ããªã³ã°ããŠã劥åœãªæ°ã®ã¬ã³ãŒããåŸãããŸãã ããã§ãªãå Žåã¯ãæåã®ã±ãŒã¹ã§ã¯ãµãã²ãŒãããŒã䜿çšã§ããŸãïŒã»ãšãã©ã®å Žåãããè¡ãããŸãïŒã2çªç®ã®ã±ãŒã¹ã§ã¯ãéžæã劥åœãªéïŒããšãã°100,000ïŒã«å¶éããããéšåçã«ããŒãéžæããŠç·©åçãªæ±ºå®ãè¡ãããšãã§ããŸãã
DB_get_countç䌌ã³ãŒãé¢æ°ãšã®é¡æšã«ãããDB_get_keysãšåŒã³ãŸã
2çªç®ã®ã¹ãããã¯ãæå®ããããã£ã«ã¿ãŒã«åŸã£ãŠããŒã¿éžæé¢æ°ãNããN + M-1ã«æžãæããæž¡ãããããŒé åã«å¯Ÿå¿ããããŒãæã€Nã¬ã³ãŒããå³å¯ã«é åå ã®é åºã§éžæããé¢æ°ã«ãœãŒãããŸãã 圌女ããµã€ã³ã«ããŸããã
DB_get_records_by_keys(*K, N)
ãããã§Kã¯ç®çã®ãã€ã³ãããã®ããŒã®é
åã®ã¢ãã¬ã¹ã§ãïŒã€ãŸããMã§ãNã¯ãããã®ããŒããéžæããã¬ã³ãŒãã®æ°ã§ããæ¬äŒŒã¢ã«ãŽãªãºã ã¯æ¬¡ã®ããã«ãªããŸãã
while (1) { create_filter(FormData, &F, &S); // F S // FormData DB_get_keys(F, S, K); // K F S while (1) // , F S ( ) { DB_get_records_by_keys(&(K[M]), N); // N , M if (SORT_OR_FILTER_CHANGED == do_navigation(FormData, C, &N, &M, &S)) // { break; // - } } }
ããã§ãå€å žçãªãã®ãšæ¯èŒããå®è¡é床ã®å®æ§çè©äŸ¡ãè©Šã¿ãŸãããã ããã¯ãšã³ãããéžæãããããŒã®é åã®è»¢éæéã¯ãå¿ èŠãªããŒã¿ãæ€çŽ¢ããæéãšæ¯èŒããŠç¡èŠã§ãããšä»®å®ããŸãïŒããã¯éåžžãå°éã®ããŒã¿ãšããŒã¿ããŒã¹ãµãŒããŒãšã¢ããªã±ãŒã·ã§ã³ãµãŒããŒéã®é©åãªãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ã転éããå Žåã§ãïŒã æäœã®äžè¬çãªã¢ã«ãŽãªãºã ã¯å€æŽãããªããããDB_get_countããŒã¿ããŒã¹é¢æ°ã®éããæ¯èŒããã ãã§æžã¿ãŸãã DB_get_keysããã³DB_get_records ?? DB_get_records_by_keysã
ã»ãšãã©ã®å ŽåãDB_get_countã¯ãäž»ã«ãã£ã«ã¿ãŒã«ãã£ãŠéžæãããè¡ãã«ãŠã³ãããïŒã€ãŸãããã©ã€ããªè¡ããŒãã«ãŠã³ãããïŒããã«å éšãœãŒããå¿ èŠãšãããSQLãšã³ãžã³ãããããã®ããŒãçºè¡ããå¿ èŠããªããããå°ãéãåäœããŸãã æ¯èŒã®ããã«ã2ã€ã®å®è¡èšç»ïŒ
DB_get_recordsãšDB_get_records_by_keysã®æ¯èŒã¯ããããã«ããŠããæããã«æåã®æ¹æ³ãæ¯æããŸããã äž»ããŒã«ããã¬ã³ãŒãã®ååŸã¯ãæ€çŽ¢æäœã®ã»ãã®äžéšã§ãã
çµæãšããŠãæ°ããæ¹æ³ã¯ã²ã€ã³ãæäŸãããã£ã«ã¿ãŒãããé¢åã«ãããã£ã«ã¿ãŒãŸãã¯ãœãŒãåºæºãå€æŽããæäœããšã®ãŠãŒã¶ãŒã«ããããŒãžãããã®å¹³åæ°ãå¢ãããšäºæž¬ããŸãã ãŸãããã®ã¡ãœããã䜿çšããŠåããã£ãŒã«ãã®ãœãŒãåºæºãå察ã«å€æŽããïŒçµ±èšçã«éåžžã«é »ç¹ãªæäœïŒããšã¯ãéã«ããŒã§ã¬ã³ãŒããéžæããDB_get_records_by_keysã«ããã²ãŒãããŠãã©ã¡ãŒã¿ãŒãè¿œå ãããšãã«ãæåã®èŠçŽ ãžã®ãã€ã³ã¿ãŒãå転ããã ãã§ãéåžžã¯ããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããã«å®è¡ã§ããããšã«æ³šæããŠãã ãã転éããã泚æã
ããŒã¿ããŒã¹ã®æŠå¿µå šäœãå®è£ ãããšãã芳ç¹ããèŠããšãæ®ã£ãŠããããšã1ã€ã ããããŸããçµæãšããŠåºåãé åå ã®ããŒã®é åºãä¿æããããã«ãããŒé åããã©ã¡ãŒã¿ãŒãšããŠçµ±èšãŸãã¯æé ã«å¹ççã«æž¡ãæ¹æ³ã¯ïŒ
ãã®ã¿ã¹ã¯ã2ã€ã«åå²ããŸãããã©ã¡ãŒã¿ãŒãšããŠé åãããŒã¿ããŒã¹ã³ãŒãã«è»¢éããå®éã«ã¯é åºãç¶æããŸãã æåã®åé¡ã«å¯Ÿããããã€ãã®è§£æ±ºçããããŸã-XMLãŸãã¯CSVè¡šçŸã«åºã¥ãããŸãã¯ããŒãã«å€æ°ã®äœæãšå ¥åã å ¥åé åãäžé£ã®æååã«å€æããSQLã³ãŒãèªäœã¯ãåçSQLã¯ãšãªãããã·ãŒãžã£ããŸãã¯ããŒãã«é¢æ°ãšããŠå®è¡ã§ããŸãã
æãæè»ãªããŒãžã§ã³ã¯ãCTEã䜿çšããããŒãã«é¢æ°ïŒTFïŒãšããŠã®ãã€ããã¯ã¹ïŒããããå ±éããŒãã«åŒïŒã§ãããMS SQL 2008ãåã蟌ã¿ããŒã¿ãåŠçããããã®ååž°ã¯ãšãªãäœæã§ããŸãã
CTEã®ãã®æ©èœãšãTFãè€åã¯ãšãªã®ããŒãã«ãœãŒã¹ãšããŠäœ¿çšã§ããæ©èœã䜿çšããŸãã
䞊ã¹æ¿ãé åºãä¿æããã¿ã¹ã¯ã¯ãè¿ãããTFããŒãã«ã®æ§é ã«IDãã£ãŒã«ããè¿œå ããç®çã®ã·ãŒãå€ãšå¢åå€ïŒå€éšã§äžŠã¹æ¿ããããããã«ïŒãè¿œå ããè¿ãããããŒãã«ïŒå éšïŒã«ã¬ã³ãŒããæ¿å ¥ããæ瀺çãªé åºã瀺ãããšã§è§£æ±ºãããŸãã ãã®çµæãæ©èœã¯æ¬¡ã®ããã«ãªããŸããã
CREATE FUNCTION [dbo].[TF_IDListToTableWithOrder] ( @ListString varchar(MAX), @Delim char(1) ) RETURNS @ID TABLE ( RowIdx INT IDENTITY(0, 1) PRIMARY KEY CLUSTERED, -- ID INT -- ) AS BEGIN SET @ListString = REPLACE(@ListString, ' ', '') IF LTRIM(RTRIM(ISNULL(@ListString, ''))) = '' RETURN -- , SET @ListString = @ListString + @Delim -- , CHARINDEX > 0, ; -- CTE WITH IDRows (ID, Pos) AS ( -- ( ) SELECT CONVERT(INT, SUBSTRING(@ListString, 1, CHARINDEX(@Delim, @ListString, 1) - 1)), CHARINDEX(@Delim, @ListString, 1) + 1 UNION ALL -- ( , ) SELECT CONVERT(INT, SUBSTRING(@ListString, Pos, CHARINDEX(@Delim, @ListString, Pos) - Pos)), CHARINDEX(@Delim, @ListString, Pos) + 1 FROM IDRows WHERE Pos < LEN(@ListString) -- ) -- CTE INSERT INTO @ID (ID) SELECT ID FROM IDRows ORDER BY Pos -- - .. OPTION (MAXRECURSION 32767) -- 100 ( , ) RETURN END
äŸã䜿çšããŠèª¬æããŸãã
ãã¹ãããŒã¿ã§ããŒãã«ãäœæããããããéåžžã«å€æ§ã§ããããšã確èªããŸã;ïŒïŒ
DECLARE @testdata TABLE (ID INT IDENTITY PRIMARY KEY CLUSTERED, Name VARCHAR(128)) INSERT INTO @testdata SELECT TOP 1000 A.name + B.name FROM sysobjects A CROSS JOIN sysobjects B ORDER BY NEWID() SELECT * FROM @testdata
DB_get_keysé¢æ°ã䜿çšããŠããŒã®éžæãã·ãã¥ã¬ãŒãããç®çã®ãã£ãŒã«ãã§éãœãŒãããããã«CSVã«å€æããŸãã
DECLARE @STR VARCHAR(MAX) = '' SELECT TOP 20 @STR = @STR + ',' + CONVERT(VARCHAR, ID) FROM @testdata WHERE Name LIKE 'C%' ORDER BY Name DESC IF LEN(@STR) > 0 SET @STR = RIGHT(@STR, LEN(@STR)-1) SELECT @STR
æåŸã«ãDB_get_records_by_keysãæš¡å£ããŸãã
SELECT TD.* FROM @testdata TD INNER JOIN dbo.TF_IDListToTableWithOrder(@STR, ',') LTT ON TD.ID = LTT.ID ORDER BY LTT.RowIdx
ãã®ãã¹ãŠãã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãšé£æºãããã«ã¯ãããã²ãŒã·ã§ã³äžã«ãŠãŒã¶ãŒã³ã³ããã¹ãïŒWebã»ãã·ã§ã³çšïŒã«ããŒå€ã®é åãä¿åããå¿ èŠããããŸãããããã«ã¯å€§éã®ã¡ã¢ãªãå¿ èŠãšæãããŸãã ãã ããããŒãæŽæ°ã§ããããªããžã§ã¯ãã®é åã§ã¯ãªãåçŽãªã¹ã«ã©ãŒé åã«æ ŒçŽãããŠããå ŽåïŒéãã¯åºæ¬ã§ãïŒïŒã100,000ã®ããŒãã¢ããªã±ãŒã·ã§ã³ãµãŒããŒã§400 kBããå æããªããšããŸããããããã¯ãçŸä»£ã®æšæºã§ã¯ããªãå°ããã§ãã
次ã«ãããã²ãŒã·ã§ã³äžã«è¿œå /åé€ããããšã³ããªã«å¯Ÿããã¡ãœããã®æ床ã«ã€ããŠèª¬æããŸãã ãã£ã«ã¿ãŒåºæºã«è©²åœããæ°ããè¿œå ãããã¬ã³ãŒãããŠãŒã¶ãŒã«è¡šç€ºãããªãããšã¯æããã§ã- ãããã®ããŒå€ã¯ããªã¹ãå šäœãéžæãããç¬éããåŸã«è¡šç€ºãããŸãã åé€ã«é¢ããŠã¯ãåœç¶ãªãããæ¬ èœããŠããã¬ã³ãŒãã¯è¿ããããããŒã®ã»ããã«ãã£ãŠå®éã«åä¿¡ãããã¬ã³ãŒãã®æ°ã¯èŠæ±ãããæ°ãããå°ãªãå ŽåããããŸãã ãã®ç¶æ³ã¯ãåä¿¡ããã¬ã³ãŒãã®IDãèŠæ±ãããã¬ã³ãŒããšæ¯èŒããäžè¶³ããŠããã¬ã³ãŒãã®ä»£ããã«ãç£èŠäžã®ã¬ã³ãŒããåé€ãããŸãããã¿ã€ãã®ã¹ã¿ãã衚瀺ããããšã«ãããã¢ããªã±ãŒã·ã§ã³å±€ã§åŠçã§ããŸãã ãŸãã¯ãããžãã¹ããŒãã«ã䜿çšããããŒãã«é¢æ°ã®çµæã®LEFT JOINãäœæã§ããŸãïŒãã®å Žåããªã¢ãŒãã¬ã³ãŒãã®ãã¹ãŠã®ãã£ãŒã«ãã¯NULLã«ãªããŸãïŒããã®äºå®ã¯ã¯ã©ã€ã¢ã³ãã§åŠçãããŸãã äžè¬çã«ããªãã·ã§ã³ãå©çšå¯èœã§ãã
ãããŠæåŸã ãã®æ¹æ³ã¯ããªã³ã©ã€ã³ãªãŒã¯ã·ã§ã³ã·ã¹ãã ãã¢ããã°ã¬ãŒãããŠãéžæãããããããã£ã«ã¿ãŒïŒããŒãžãŸãã¯1ã€ãã€-ååŸïŒã§è¡šç€ºããå ¥æããã³ç¶ç¶çãªããã²ãŒã·ã§ã³ã®å¯èœæ§ãããå Žåã«äœ¿çšãããŸããã ãã®ãããªã¢ããªã±ãŒã·ã§ã³ã§ã¯ã1ã€ã®ãã£ã«ã¿ãŒã§ã®ããã²ãŒã·ã§ã³ã®å¹³åæ°ãéåžžã«å€ããããåŸæ¥ã®ããŒãžããŒã·ã§ã³ãããã«çœ®ãæããããšã¯ãããŒã¯è² è·æã«SQLãµãŒããŒã®éåœãå€§å¹ ã«è»œæžããããšãå¯èœã«ããå¹æçãªæ段ã®1ã€ã§ãã