>想象一下,我有一个包含大量数据的数据库,用户可以从中搜索。
典型搜索的结果通常约为 20-100 行,然后进行分页(每页 20 行)。
我想到了两种处理这些页面导航的方法,想知道这些是否有任何优点和/或缺点,以及是否有更好的选择。
-
查询一次,将结果存储在变量
$_SESSION
并根据当前页面筛选行。我想出这个的原因是进行一次数据检索,而不必为用户导航的每个页面连接到数据库。我不知道它比我想出的其他替代方案更好还是更差。session_start(); $search = rawurldecode($_GET['search']); //search word $interval = rawurldecode($_GET['interval']); //rows per page $page = rawurldecode($_GET['page']); //page $min_row = $interval * ($page-1)+1; $max_row = $interval * $page; //query if (no results stored or first page) && the current search is not the previous search if((empty($_SESSION['SEARCH_RESULTS']) || $page == 1) && $_SESSION['SEARCH_RESULTS']['TERM'] != $search){ $_SESSION['SEARCH_RESULTS'] = array(); $_SESSION['SEARCH_RESULTS']['TERM'] = $search; $query = "exec usp_Search '$search'"; $dbh = new DBH; $dbh->Connect()->Query($query); while($row = $dbh->Fetch_Array()){ $_SESSION['SEARCH_RESULTS']['ROWS'][] = $row; } } for($j = 0; $j < count($_SESSION['SEARCH_RESULTS']['ROWS']); $j++){ $row = $_SESSION['SEARCH_RESULTS']['ROWS'][$j]; //ignore all other rows not on the page if($j < ($min_row-1) || $j > $max_row) continue; //print stuff }
-
逐页查询。查询和分页非常简单。
//Query $search = rawurldecode($_GET['search']); $interval = rawurldecode($_GET['interval']); $page = rawurldecode($_GET['page']); $min_row = $interval * ($page-1)+1; $max_row = $interval * $page; $query = "exec usp_Search '$search', $min_row, $max_row"; $dbh = new DBH; $dbh->Connect()->Query($query); while($row = $dbh->Fetch_Array()){ //print stuff }
替代方案中的 SQL 过程
-
只是一个带有 SELECT 查询的过程
SELECT COL1, COL2, COL... FROM TABLE1 WHERE ( COL1 LIKE '%'+@search+'%' OR COL2 LIKE '%'+@search+'%' OR COL... LIKE '%'+@search+'%' )
-
是一个创建临时表,然后从变量中从开始到结束选择行的过程。
SELECT COL1, COL2, COL..., ROW_NUMBER() OVER (ORDER BY COL1) AS [ROW_NUMBER] INTO #result FROM TABLE1 WHERE ( COL1 LIKE '%'+@search+'%' OR COL2 LIKE '%'+@search+'%' OR COL... LIKE '%'+@search+'%' ) SELECT COL1, COL2, COL... FROM #result WHERE ROW_NUMBER BETWEEN @row_start AND @row_end
由于至少以下几个原因,您确实无法将所有结果存储在_SESSION
中:
- 用户可以同时进行多次搜索
- 搜索结果可能会在用户页面加载之间发生变化。
第二点取决于您更新数据库的频率,但需要考虑这一点。 第一个是主要的,但如果你以巧妙的方式存储会话,你也可以绕过它(但你也不想_SESSION
变得太大)。 这与性能无关。
一次获取所有结果并存储到_SESSION
的另一个注意事项是,大多数用户每次访问可能只发出一个搜索请求。 我知道你认为他们总是会查看所有 100 个结果,但如果这些结果中的很大一部分甚至没有被使用,你只是为了保存一两个查询就浪费了很多。 由您来弄清楚用户如何导航。
在读到这只会被 20-30 人使用并且每天只有 70 行之后,我很满意地说你在浪费时间试图提高性能。 选择以后在发生重大更改时更容易更新的代码。
请考虑以下场景:
- 用户搜索数据库中存储了 100 个结果的术语。
- 查询数据库一次,获取所有 100 个结果,并将它们存储在会话中。
- 用户在前 5 个结果中找到他要查找的内容并离开搜索页面。
最后,您"过热"数据库以免费获取 95 行。如果这 100 个结果是 1000 或 10.000 怎么办?
在我看来,在单个查询中获取所有结果并将结果存储在会话中是降低性能的"可靠方法"。