0

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 秒しかかかりません。

テーブルが急速に成長しており、すでに遅すぎるため、クエリを高速化する方法やテーブル構造を最適化する方法について考えてください。

4

1 に答える 1

0

まず、指定した主キーが正しくないため、投稿したテーブル構造filingが正しくありません。私はあなたが意味すると仮定しますnumber。さらに、 のテーブル定義を指定していないためcompany、これに関するアドバイスを提供することはやや困難です。

しかし、どちらのコメントも正しいです。いくつかのインデックスが必要です。クエリに基づいて、おそらく次のインデックスを作成する必要があります。

ALTER TABLE companyADD INDEX ( cik)
ALTER TABLE dataADD INDEX ( number)

また、data.elementname が実際に MEDIUMTEXT である必要があるかどうかを確認することをお勧めします。これはかなり巨大な列です。残りのデータが提供したサンプル データのように見える場合は、おそらくそれを varchar に変更する必要があります。TEXT 列は、格納方法が原因で、パフォーマンスに深刻な影響を与える可能性があります。

さらに、現在文字列である PRIMARY KEY 数値列は、実際には INT 型の別の列に再フォーマットできるように見えます。VARCHAR PRIMARY KEY 列は、非常に大きいという理由だけで、INT ほど効率的ではないことに注意してください。

最後に、22k 行はそれほど多くのデータではありません。my.cnf の設定を確認してください。key_buffer の値が小さすぎて、インデックス全体がメモリに収まらない可能性があります。さらに、すべてをメモリに保持する innodb_buffer_pool 値と組み合わせて、これらのテーブルに INNODB を使用することを検討することもできます。

于 2013-01-19T19:20:13.447 に答える