MySQL-Query太慢了

时间:2013-01-19 18:30:53

标签: mysql performance optimization select

我在MySQL数据库中使用以下表格:

--
-- Table structure for table `company`
--

CREATE TABLE IF NOT EXISTS `company` (
  `numb` varchar(4) NOT NULL,
  `cik` varchar(30) NOT NULL,
  `sNumber` varchar(30) NOT NULL,
  `street1` varchar(255) NOT NULL,
  `street2` varchar(255) NOT NULL,
  `city` varchar(255) NOT NULL,
  `state` varchar(100) NOT NULL,
  `zip` varchar(100) NOT NULL,
  `phone` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  `dateChanged` varchar(30) NOT NULL,
  `name2` varchar(255) NOT NULL,
  `seriesId` varchar(30) NOT NULL,
  `symbol` varchar(10) NOT NULL,
  `exchange` varchar(20) NOT NULL,
  PRIMARY KEY (`cik`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


INSERT INTO `company` (`numb`, `cik`, `sNumber`, `street1`, `street2`, `city`, `state`, `zip`, `phone`, `name`, `dateChanged`, `name2`, `seriesId`, `symbol`, `exchange`) VALUES
('6798', 'abc', '953551121', '701 AVENUE', '', 'GLENDALE', 'CA', '91201-2349', '818-244-8080', '', '', 'Public Store', '', 'PSA', 'NYSE')


--
-- Table structure for table `data`
--

CREATE TABLE IF NOT EXISTS `data` (
  `id` int(100) NOT NULL AUTO_INCREMENT,
  `number` varchar(100) NOT NULL,
  `elementname` mediumtext NOT NULL,
  `date` varchar(100) NOT NULL,
  `elementvalue` longtext NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=18439;

INSERT INTO `data` (`id`, `number`, `elementname`, `date`, `elementvalue`) VALUES
(1, '0001393311-10-000004', 'StockholdersEquityIncludingPortionAttributableToNoncontrollingInterest', '2009-12-31', '3399777000')


--
-- Table structure for table `filing`
--

CREATE TABLE IF NOT EXISTS `filing` (
  `number` varchar(100) NOT NULL,
  `file_number` varchar(100) NOT NULL,
  `type` varchar(100) NOT NULL,
  `amendment` tinyint(1) NOT NULL,
  `date` varchar(100) NOT NULL,
  `cik` varchar(30) NOT NULL,
  PRIMARY KEY (`accession_number`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `filing` (`number`, `file_number`, `type`, `amendment`, `date`, `cik`) VALUES
('0001393311-10-000004', '001-33519', '10-K', 0, '2009-12-31', '0000751653'),
('0000751652-10-000006', '001-08796', '10-K', 0, '2009-12-31', '0000751652')

数据表有大约22.000个条目,归档和公司表每个大约有400个条目。我希望将来能够使用更多条目来操作数据库。

我执行以下查询,该查询选择具有给定类型的最新项目:

SELECT data.elementname, data.elementvalue, company.name2 FROM data
JOIN filing ON data.number = filing.number
JOIN company ON filing.cik = company.cik
WHERE elementname IN ('Elem1', 'Elem2', 'Elem3', 'Elem4', 'Elem5', 'ElemN')

 AND number IN (
  SELECT number
   FROM filing
   WHERE filing.cik IN ('cik1', 'cik2', 'cikN')
   AND filing.type = '1L'
   GROUP BY filing.cik
)

完成需要约0.28到0.4秒,这似乎非常慢。

当我执行没有以下行的查询时

WHERE filing.cik IN ('cik1', 'cik2', 'cikN')

它只需要约0.035秒。

任何想法如何加快查询速度或优化表结构,因为表格正在快速增长而且已经太慢了。

1 个答案:

答案 0 :(得分:0)

首先,您为filing发布的表结构不正确,因为您指定的主键没有。我假设你的意思是number。此外,您没有为company指定表定义,这使得尝试为此提供建议有点困难。

但是,这两条评论都是正确的。你需要一些索引。根据查询,您可能应该使用以下索引。

  

ALTER TABLE company ADD INDEX(cik
  ALTER TABLE data ADD INDEX(number

我还建议看看data.elementname是否真的需要是MEDIUMTEXT,这是一个非常庞大的专栏。如果其余数据看起来像您提供的示例数据,则应该将其更改为varchar。 TEXT列可能会因存储方式而导致严重的性能损失。

此外,您的PRIMARY KEY编号列(当前是字符串)看起来好像可以重新格式化为实际类型为INT的不同列。请记住,VARCHAR PRIMARY KEY列不会像INT那样高效,只是因为它们更大。

最后,22k行并不是那么多数据。你应该看看你的my.cnf设置。您的key_buffer值可能太小,无法完全将索引放入内存中。此外,您可能需要考虑将INNODB用于这些表,并结合innodb_buffer_pool值,以便将所有内容保存在内存中。