1

votersテーブル内のアクティビティ(700万レコード)に基づいて、テーブルからの投票者(100万レコード)を一覧表示するクエリを作成していますvotes。基準は次のとおりです。

  • 総選挙(GE)は年に1回だけ行われ、2004年以降のGEのみがカウントされます。

  • 前述のGEのうち、投票者の10%から50%が投票したGEのみをカウントする必要があります。

重要性の低い情報:

  • スキーマは変更できません。固定幅のテキストファイルとして提示され、スクリプトを介してアップロードされ、他の目的に使用されます。

  • 現在のアクティブな投票者のリストとその投票履歴のみが利用可能です。以下のクエリには、年が1減少するたびに、上限しきい値を10,000人の投票者で減少させる方程式を含めました。これは完全ではありませんが、有効なGEを維持しながら、不要なGEを除外しているようです。

たとえば、2005年、2006年、2007年、2009年、2010年、2011年に10万から50万人の投票者が投票した場合、それらの年に投票した投票者のみをリストに表示したいと思います。

mysqlfiddleはここにあります

スキーマは次のとおりです。

CREATE TABLE IF NOT EXISTS `voters` (
  `CountyEMSID` varchar(9) COLLATE utf8_unicode_ci NOT NULL,
  `LastName` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `FirstName` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `MiddleInitial` varchar(1) COLLATE utf8_unicode_ci NOT NULL,
  `NameSuffix` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
  `HouseNumber` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  `HouseNumberSuffix` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  `ApartmentNumber` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
  `StreetName` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `City` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
  `Zip` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
  `ZipCode4` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
  `MailingAddress1` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `MailingAddress2` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `MailingAddress3` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `MailingAddress4` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `DOBY` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
  `DOBM` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `DOBD` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `Gender` varchar(1) COLLATE utf8_unicode_ci NOT NULL,
  `Party` varchar(3) COLLATE utf8_unicode_ci NOT NULL,
  `Other` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `ED` varchar(3) COLLATE utf8_unicode_ci NOT NULL,
  `AD` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `CD` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `CO` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `SD` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `CC` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `JD` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `RegY` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
  `RegM` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `RegD` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `Status` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `VoterType` varchar(1) COLLATE utf8_unicode_ci NOT NULL,
  `StatusChangeY` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
  `StatusChangeM` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `StatusChangeD` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `LastVoted` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
  `Telephone` varchar(12) COLLATE utf8_unicode_ci NOT NULL,
  `County` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  KEY `districts` (`CountyEMSID`,`ED`,`AD`,`CD`,`CO`,`SD`,`CC`,`JD`),
  KEY `vsn` (`CountyEMSID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE IF NOT EXISTS `votes` (
  `CountyEMSID` varchar(9) COLLATE utf8_unicode_ci NOT NULL,
  `County` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `AD` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `ED` varchar(3) COLLATE utf8_unicode_ci NOT NULL,
  `Party` varchar(3) COLLATE utf8_unicode_ci NOT NULL,
  `ElectionDateY` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
  `ElectionDateM` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `ElectionDateD` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `ElectionType` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `VoterType` varchar(1) COLLATE utf8_unicode_ci NOT NULL,
  KEY `CountyEMSID` (`CountyEMSID`),
  KEY `perfect` (`CountyEMSID`,`ElectionDateY`,`ElectionType`),
  KEY `CountyEMSID_2` (`CountyEMSID`,`ElectionDateY`,`ElectionType`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

これまでのところ、テーブルから投票者の一意のID(CountyEMSID)をリストするだけの次のクエリがありvotesます。mysqlfiddleで動作しますが、phpmyadminでハングします。

SELECT DISTINCT CountyEMSID
FROM `votes` 
WHERE ElectionDateY IN 
(
SELECT ElectionDateY
FROM `votes`
WHERE ElectionType = 'GE' 
AND ElectionDateY >= 2004 
GROUP BY ElectionDateY 
HAVING COUNT(*) < ((0.5 * (SELECT COUNT(*) FROM `voters`)) - ((YEAR(CURRENT_TIMESTAMP()) - ElectionDateY) * 10000)) 
AND COUNT(*) > (0.1 * (SELECT COUNT(*) FROM `voters`))
)

votesこのクエリを最適化し、テーブルから対応するすべての投票者情報を返すように変更することで、助けていただければ幸いです。

4

1 に答える 1

2

MySQLinは句の最適化が非常に不十分です。基本的に、処理される行ごとにサブクエリを再実行します。計算をfrom句に移動する必要があります。これが私の試みです:

select distinct v.*
from votes v join
     (select electiondatey, count(*) as NumYVotes
      from votes v
      group by electiondatey
    ) ey
    on v.electiondatey = ev.electiondatey cross join
    (select count(*) as numvoters from voters) as const
where (NumYVotes < 0.5 * numvoters - year(now()) - ElectionDateY * 10000) and
      (NumYVotes > 0.1 * numvoters)

注: これはテストしていないため、おそらく構文エラーがあります。

于 2013-01-27T20:20:32.907 に答える