MyISAM后mysql查询速度慢 - > InnoDB并迁移到AWS

时间:2017-01-27 05:19:58

标签: mysql innodb amazon-rds myisam

我打算从共享托管服务器切换到AWS设置(apache / php为EC2,MySQL为RDS)。

我的共享服务器上运行的php / mysql网站测试版已超过一年了。特别是一个页面总是在浏览器中快速运行(可能<3秒完全加载)。

在准备移动时,我将数据库和所有表从MyISAM更改为InnoDB。我还将默认字符集切换为utf8mb4(是latin-1或其他),并将其整理为utf8mb4_unicode_ci。有几列类似于varchar2(400)的索引,得到了&gt; 191个字符错误(因为使用utf8mb4从3byte-> 4byte移动)。我进去并手动将这些列切换为UTF-8 / utf_unicode_ci。似乎没事(没有明确的错误)

现在,我已将站点/数据库的副本移至AWS。大多数页面加载正常。这尤其是需要永远加载(> 5分钟)。我有一些相当小的EC2实例和RDS实例,所以我意识到这可能是一个问题,但我是唯一一个使用该网站(对于一个查询)并且整个数据库是&lt; 70MB。

运行解释计划显示在大多数情况下使用密钥(索引?)和一个具有74k行的“派生”表。 74k是一个非常小的数据集。我对Oracle解释计划比较熟悉,所以我很难弄清楚发生了什么。

我尝试在共享主机服务器上运行原始页面,它也变慢了!因此,我没有理由相信这是一个AWS问题。

我知道MyISAM在简单的场景中速度要快一点,但是它不应该比我新使用的InnoDB快10000000000000x?

尝试使用&gt;索引varchars的转换时出现了问题。 191个字符?是不是有可能它以某种方式打破了系统/表?如果你给他们大量的时间,查询将会完成,但他们不应该这么慢。我认为,即使指数被炸,并且它正在对74k行进行全表扫描,它甚至不应该出汗。

思想?

编辑: 找到这个帖子: https://dba.stackexchange.com/questions/75091/why-are-simple-selects-on-innodb-100x-slower-than-on-myisam 这张海报似乎也有类似的减速体验。我不能使用与他/她相同的解决方案。认为我必须将我想要返回的所有列放入索引中是疯狂的。这不是每个人都接受的东西吗?

1 个答案:

答案 0 :(得分:0)

好的,我明白了。是我的错(不奇怪)。很久以前我写了这个问题,然后我真的知道自己在做什么。肯定有改进的余地......

查询类似于:

TableA (main table of focus)
  aID (pk)
  bID (fk)
  locationID (fk)
  rowTitle

TableB 
  bID (pk)
  locationID (fk)

TableLocations
  locationID (pk)
  locationName

我想基本上使用A的位置(如果它存在),但如果A没有A位置,则回到B的位置。 (A总是与B相关联。)

我做了一些像

 SELECT
   rowTitle,
   locationName
 FROM
   TableA a, TableB b, TableLocations loc
 WHERE
  a.bID = b.bID
  AND
  ( a.locationID = loc.locationID
    OR 
   (a.locationID IS NULL AND b.locationID = loc.locationID)
  )

它运行良好,并且在使用MyISAM时总是返回我想要的内容。这很快。然而,sh $&amp;因为某些原因我搬到InnoDB时碰到了墙。在执行此查询的计划时,没有关于引擎如何不同的线索。我想在某些时候,当数据集足够大时,MyISAM会窒息,但由于我仍然处于dev / uat,因此数据很小。

我已经搬到了结构更好的地方,如:

 SELECT 
   rowTitle
   CASE WHEN loc1.locationID IS NOT NULL THEN loc1.locationName
        WHEN loc2.locationID IS NOT NULL THEN loc2.locationName
   END as locationName
FROM
   TableA a
JOIN TableB b ON a.bID = b.bID
 LEFT OUTER JOIN TableLocations loc1 ON a.locationID = loc1.locationID
 LEFT OUTER JOIN TableLocations loc2 ON b.locationID = loc2.locationID

一切都很棒!我删除了很多查询和其他表格,专注于我的主要逻辑/物理问题。

查询大约是10MS,这是我所期望的。

这是我喜欢和讨厌MySQL的一件事。有时&#34;它只是有效&#34;让你看看自己的不足之处。绝对是我的错,因为第一次没有做对......

附加问题: 如果有人知道MyISAM和InnoDB如何评估第一个(坏)查询以及为什么表现如此不同,我真的很想听到它!

谢谢!