0

我正在尝试使我的数据库更加优化,并且正处于索引它的开始,但不知道如何正确地做到这一点。

我有这个查询:

$year = date("Y");
$thisYear = $year;
//$nextYear = $thisYear + 1; 
$sql = mysql_query("SELECT SUM(points) as userpoints
                                          FROM ".$prefix."_publicpoints
                                          WHERE date BETWEEN '$thisYear" . "-01-01' AND '$thisYear" . "-12-31' AND fk_player_id = $playerid");
$row = mysql_fetch_assoc($sql); 
$userPoints = $row['userpoints'];

$sql = mysql_query("SELECT 
                       fk_player_id
                    FROM ".$prefix."_publicpoints
                    WHERE date BETWEEN '$thisYear" . "-01-01' AND '$thisYear" . "-12-31'
                    GROUP BY fk_player_id
                    HAVING SUM(points) > $userPoints");
$row = mysql_fetch_assoc($sql);
$userWrank = mysql_num_rows($sql)+1;

我不知道如何索引这个?我已经尝试索引 fk_player_id 但它仍然查看所有行(287937)。

我已将日期字段编入索引,这在 EXPLAIN 中返回:

1 SIMPLE nf_publicpoints range IDXdate IDXdate 3 NULL 143969 使用 where 和 push 条件;使用临时...

我也有 2 次呼叫同一张桌子......可以一次完成吗?

我如何索引这个和/或它可以做得更聪明?

4

3 回答 3

1

您绝对应该花一些时间阅读索引,关于它的文章很多,了解正在发生的事情很重要。

从广义上讲,索引对表的行进行排序。

为简单起见,假设一个表只是一个大的 CSV 文件。每当插入一行时,它都会插入到最后。所以表的“自然”顺序就是插入行的顺序。

想象一下,您在一个非常基本的电子表格应用程序中加载了该 CSV 文件。这个电子表格所做的只是显示数据,并按顺序对行进行编号。

现在假设您需要在第三列中找到所有具有某个值“M”的行。鉴于你有什么可用的,你只有一个选择。您扫描表检查每一行的第三列的值。如果您有很多行,则此方法(“表扫描”)可能需要很长时间!

现在想象一下,除了这个表之外,你还有一个索引。此特定索引是第三列中值的索引。该索引以某种有意义的顺序(例如,按字母顺序)列出了第三列中的所有值,并且为每个值提供了该值出现的行号列表。

现在您有了一个很好的策略来查找第三列的值为 M 的所有行!例如,您可以执行二进制搜索!虽然表扫描需要您查看 N 行(其中 N 是行数),但二进制搜索只需要您查看 log-n 索引条目,在最坏的情况下。哇,那肯定容易多了!

当然,如果你有这个索引,并且你正在向表中添加行(最后,因为这就是我们的概念表的工作方式),你需要每次都更新索引。因此,您在编写新行时会做更多的工作,但在搜索某些内容时会节省大量时间。

因此,一般而言,索引会在读取效率和写入效率之间进行权衡。在没有索引的情况下,插入可以非常快——数据库引擎只是在表中添加一行。添加索引时,引擎必须在执行插入时更新每个索引。

另一方面,读取变得更快。

希望这涵盖了您的前两个问题(正如其他人所回答的那样——您需要找到正确的平衡点)。

您的第三种情况要复杂一些。如果您使用 LIKE,索引引擎通常会帮助您将读取速度提高到第一个“%”。换句话说,如果您选择 WHERE column LIKE 'foo%bar%',数据库将使用索引查找列以“foo”开头的所有行,然后需要扫描该中间行集以找到子集包含“栏”。SELECT ... WHERE column LIKE '%bar%' 不能使用索引。我希望你能明白为什么。

最后,您需要开始考虑不止一列的索引。这个概念是相同的,并且行为类似于 LIKE 的东西——本质上,如果你在 (a,b,c) 上有一个索引,引擎将继续尽可能地从左到右使用索引。因此,对 a 列的搜索可能会使用 (a,b,c) 索引,就像对 (a,b) 的搜索一样。但是,如果您在搜索 WHERE b=5 AND c=1),引擎将需要进行全表扫描

希望这有助于阐明一点点,但我必须重申,您最好花几个小时挖掘深入解释这些事情的好文章。阅读特定数据库服务器的文档也是一个好主意。查询计划者实现和使用索引的方式可以有很大的不同。

更多信息和示例访问这里:http: //blog.sqlauthority.com/category/sql-index/

于 2013-02-09T11:37:22.460 回答
0

为什么不索引日期列,看看这是如何在查找中评估的主要标准?

于 2013-02-09T11:36:50.700 回答
0

尝试在日期列上创建索引,索引 fk_payer_id 对这个查询没有帮助。如果不起作用 - 粘贴解释...

有关 Mysql 中索引的更多信息,请参见此处:http ://hackmysql.com/case1

于 2013-02-09T11:28:15.360 回答