【问题标题】:Will indexes on my MySQL tables improve my website performance?我的 MySQL 表上的索引会提高我的网站性能吗?
【发布时间】:2014-03-04 21:47:25
【问题描述】:

我有两个非常简单的表:

CREATE TABLE `tbl_words` (
  `fld_id` int(11) NOT NULL AUTO_INCREMENT,
  `fld_word` varchar(255) DEFAULT NULL,
  `fld_cat_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`fld_id`)
);

这包含一长串单词,其中列出了大约 10,500 个单词。每个词里面也有一个CatID,对应这个表中的一个词类:

CREATE TABLE `j_word_cat` (
  `fld_id` int(11) NOT NULL AUTO_INCREMENT,
  `fld_cat` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`fld_id`)
);

从这些表中获取数据的页面每月获得大约 500,000 次页面浏览量。表中的数据是相当静态的,很少更新。

我发现我使用的 MySQL 数据库每天都会返回很多这样的错误:

查询期间与 MySQL 服务器的连接丢失

我想知道 - 如果我向“tbl_words”表添加一个新索引(例如,一个名为“catID”的索引并链接到“fld_cat_id”列),性能会得到改善。

或者我应该创建一个同时使用两者的索引,例如fld_id 和 fld_cat_id 一起?

任何建议将不胜感激。

谢谢

更新

我的查询非常简单 - 我实际上并没有加入表格。

用户从 j_word_cat 表中选择一个类别,然后该 ID 用于生成随机的单词列表,例如这些是我正在运行的一些常见查询:

-- Category table to populate SELECT drop down list of categories:
SELECT fld_cat, fld_id FROM j_word_cat ORDER BY fld_cat;

-- common word table selects:
-- the NOT IN bit is to exclude one category which I want to exclude by default unless the user actually chooses it
SELECT fld_word FROM tbl_words WHERE fld_cat_id NOT IN (24) ORDER BY RAND() LIMIT 50;

-- note that the value of 15 would vary depending on the category the user selected
-- 15 is just an example

SELECT fld_word FROM tbl_words WHERE fld_cat_id = 15 ORDER BY RAND() LIMIT 50;

SELECT fld_word FROM tbl_words ORDER BY RAND() LIMIT 60;

【问题讨论】:

  • 您对这些表运行了哪些查询?需要该信息来确定所需的最佳索引。
  • 简短的回答是肯定的!但也可以发布您的查询,它们可能也需要优化!
  • 感谢您的快速回复 - 我已经发布了一些最常用的查询

标签: mysql sql


【解决方案1】:

索引会加快选择速度并减慢插入和更新速度,但是我经常处理具有数百万条记录的表,我们可以通过适当的索引将查询速度从 4 到 5 分钟降低到不到 1 秒,其中对插入和更新的影响可以忽略不计。

如果您创建了一些索引并想知道它们是否被使用,那么您可以使用 mysql Explain 工具查看您的查询

EXPLAIN SELECT fld_word 
FROM tbl_words WHERE fld_cat_id NOT IN (24) 
ORDER BY RAND() LIMIT 50;

在您的结果中,您将看到可能的索引列表和最终选择的索引。特别注意“行”列,因为这将显示它必须为结果中的每个表扫描多少行。

最终,您希望争取在您的服务器上运行零个未索引查询,并且运行的查询应扫描尽可能少的行。我的建议是在您的 mysql.ini 文件中打开未索引查询日志并在合理的情况下修复所有查询。

如果您加入或订购或使用可以提高性能的地方,如果您只是选择无序信息而不加入,则不会。

fld_cat_id 应该被索引

您的主键应该这样声明。如果你想完全优化它们,那么让它们不为 null、unsigned、auto_increment 并将它们分配为主键。

如果您正在执行类似 where fld_word = 'bla' 的操作,则应将其与使用的任何连接键一起编入索引。

如果您有一个小型数据库,那么性能提升是可以忽略不计的,但这不是懒惰的好设计的理由。

更多阅读:

【讨论】:

    【解决方案2】:

    根据您的查询,您需要以下索引

    j_word_cat(fld_cat) # because you are sorting by this field
    tbl_words(fld_cat_id) # because you are filtering by this field
    

    由于您没有加入表,也没有按不同的列进行过滤,因此不应创建不需要的复合索引。

    我会推荐你​​阅读this article,这对我有很大帮助。注意:有点老了,讲的是SQL Server,但是理解SQL索引很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-23
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多