php - 复杂的 MySQL 表模式及其性能

标签 php mysql sql performance

我几年前为我的 mysql 表编写了这段代码,现在网站流量巨大,我觉得有必要改变和改进它。

SELECT ns.*
    FROM stories AS ns
    WHERE section='news' 
      AND title!='draft'
      AND ( 
          FIND_IN_SET('4', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('5', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('6', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('7', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('8', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('9', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('10', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('11', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('12', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('13', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('14', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('15', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('16', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('17', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('18', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('19', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('20', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('21', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('22', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('23', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('24', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('25', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('26', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('27', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('28', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('29', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('30', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('31', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('32', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('33', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('34', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('35', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('36', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('37', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('38', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('39', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('40', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('41', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('42', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('43', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('44', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('45', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('46', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('47', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('48', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('49', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('50', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('51', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('52', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('53', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('54', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('55', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('56', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('57', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('58', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('59', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('60', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('61', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('62', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('63', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('64', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('65', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('66', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('67', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('68', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('69', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('70', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('71', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('72', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('73', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('74', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('75', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('76', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('77', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('78', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('79', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('80', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('81', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('82', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('83', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('84', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('85', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('86', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('87', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('88', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('89', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('90', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('91', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('92', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('94', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('95', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('96', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('97', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('98', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('99', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('100', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('101', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('102', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('103', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('104', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('105', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('106', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('107', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('108', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('109', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('110', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('111', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('112', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('113', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('114', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('115', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('116', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('117', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('118', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('119', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('120', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('121', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('122', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('123', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('125', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('126', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('127', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('128', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('129', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('130', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('131', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('132', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('133', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('134', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('135', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('136', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('137', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('138', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('139', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('140', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('141', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('142', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('144', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('145', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('146', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('147', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('148', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('149', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('150', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('151', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('152', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('153', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('154', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('155', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('156', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('157', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('158', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('159', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('160', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('161', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('162', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('163', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('164', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('165', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('166', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('167', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('168', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('169', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('170', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('171', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('172', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('173', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('174', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('175', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('176', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('177', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('178', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('179', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('180', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('181', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('182', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('183', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('184', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('185', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('186', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('187', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('188', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('189', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('190', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('191', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('192', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('193', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('194', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('195', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('196', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('197', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('198', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('199', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('200', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('201', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('202', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('203', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('204', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('206', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('207', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('208', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('209', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('210', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('211', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('212', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('213', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('214', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('215', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('216', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('217', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('218', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('219', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('220', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('221', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('222', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('223', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('224', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('225', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('226', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('227', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('228', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('229', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('230', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('231', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('232', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('233', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('234', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('235', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('236', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('237', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('238', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('239', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('240', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('241', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('242', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('243', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('244', REPLACE(jjob, '-', ','))
       OR FIND_IN_SET('245', REPLACE(jjob, '-', ','))
   ) AND time <= '2015-11-14 08:30:59'
    ORDER BY ns.hotnews DESC,ns.sid DESC

这是我的表结构:

CREATE TABLE IF NOT EXISTS `stories` (
  `sid` int(11) NOT NULL,
  `catid` int(11) NOT NULL DEFAULT '0',
  `aid` varchar(30) COLLATE utf8_bin NOT NULL,
  `title` text COLLATE utf8_bin,
  `time` datetime DEFAULT NULL,
  `hometext` text COLLATE utf8_bin,
  `bodytext` text COLLATE utf8_bin NOT NULL,
  `hotnews` int(1) NOT NULL DEFAULT '0',
  `tags` varchar(255) COLLATE utf8_bin NOT NULL,
  `approved` tinyint(1) NOT NULL DEFAULT '1',
  `section` varchar(15) COLLATE utf8_bin NOT NULL DEFAULT 'news',
  `rate` int(8) NOT NULL DEFAULT '0',
  `rates_count` int(8) NOT NULL DEFAULT '0',
  `jorganization` int(1) NOT NULL DEFAULT '0',
  `jemployment` int(1) NOT NULL DEFAULT '0',
  `jsex` int(1) NOT NULL DEFAULT '0',
  `jagelimit` int(1) NOT NULL DEFAULT '0',
  `jmarriage` int(1) NOT NULL DEFAULT '0',
  `jduty` int(1) NOT NULL DEFAULT '0',
  `jedu` int(1) NOT NULL DEFAULT '0',
  `jmajor` int(1) NOT NULL DEFAULT '0',
  `jfield` text COLLATE utf8_bin NOT NULL,
  `jjob` text COLLATE utf8_bin NOT NULL,
  `jcity` text COLLATE utf8_bin NOT NULL
) ENGINE=MyISAM AUTO_INCREMENT=71693 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

--
-- Indexes for dumped tables
--

--
-- Indexes for table `stories`
--
ALTER TABLE `stories`
  ADD PRIMARY KEY (`sid`), ADD KEY `tags` (`tags`), ADD KEY `rate` (`rate`), ADD KEY `rates_count` (`rates_count`);

当我运行查询时,如您所见,它需要超过 2 秒:

 Showing rows 0 - 24 (27875 total, Query took 2.3042 seconds.) [hotnews: 0 - 0] [sid: 71692 - 71631]

和解释:

enter image description here

最佳答案

如果您只计划最多使用一定数量的返回行,那么最简单(也是最有益)的事情之一就是添加一个 LIMIT

此外还有一些您可以快速完成的事情:

  1. 只选择您需要的字段
  2. 添加覆盖索引 ( https://www.percona.com/blog/2006/11/23/covering-index-and-prefix-indexes/ )
  3. 修改/重组工作

    我不太确定 jjob 在做什么,但您可能需要将其分离到另一个表中。例如,您可能有一个单独的 jjobs 表并创建一个连接表 (stories_jjobs) 来保存每个独特的故事/jjob 关系。

您可能想尝试的另一个选项是摆脱所有 FIND_IN_SETREPLACE 并尝试类似 AND (jjob LIKE %-6% OR jjob喜欢 %-9-% 等...)

编辑

在仔细查看您的结构之后,为了您的长期利益,您可能应该将上面的内容分成多个表。您的数据库相当小,因此创建一些查询来移动数据应该不会太痛苦。据我所知,j 列似乎包含人员或用户数据。也许您可以创建一个人员或用户表、一个工作表和一个联结表来加入故事和工作?

关于php - 复杂的 MySQL 表模式及其性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33705347/

相关文章:

MySQL - 使用 'load data infile"导入巨大的 csv

sql - SQL如果可能,将值转换为int,如果不可能,则将值设置为0

sql - 级联软删除

MySQL 5.0 根据不同的列分配编号

php - Docker:docker-compose 将文件从容器复制到主机

php - Codeigniter form_validation 总是返回 false

php - 当 MySQL 服务器消失时 Propel2 重新连接

php - 无法将表单数据插入数据库(MySQLIi)

php - 如何在php中同一表单内的另一个提交按钮使用一个提交按钮的变量

php - 更新错误。 SQLSTATE[HY093] : Invalid parameter number