5

私は現在、特許に関するプロジェクトに取り組んでおり、このプロジェクトの一環として、イリノイ大学の人々によって作成されたデータベースを使用しています
(論文: http://abel.lis.illinois.edu/UPDC )。 /USPTOPatentsDatabaseConstruction.pdf )
(私が使用しているテーブルのスキーマは少し古くなっています。非インデックス/キー値のみが欠落しています: http://i.imgur.com/44LHS3L.png )

タイトルにあるように、クエリを最適化しようとしています。

SELECT 
        PN,
        AN,
        grants.GrantID,
        grants.FileDate,
        grants.IssueDate,
        grants.Kind,
        grants.ApplicationID,
        assignee_g.OrgName,
        GROUP_CONCAT(DISTINCT CONCAT_WS(', ', assignee_g.City, assignee_g.State, assignee_g.Country) separator ';') as Assignee,
        GROUP_CONCAT(DISTINCT CONCAT_WS(', ', inventor_g.FirstName, inventor_g.LastName) separator ';') as Inventor,
        GROUP_CONCAT(DISTINCT CONCAT_WS(', ', inventor_g.City, inventor_g.State, inventor_g.Country) separator ';') as Inventor_address,
        GROUP_CONCAT(DISTINCT CONCAT_WS(', ', usclass_g.Class, usclass_g.Subclass) separator ';') as USClass,
        intclass_g.Section,
        intclass_g.Class,
        intclass_g.Subclass,
        intclass_g.MainGroup,
        intclass_g.SubGroup
FROM
    (
    SELECT grants.GrantID as CitingID, CitedID as PN, grants2.ApplicationID AS AN
    FROM
        gracit_g, grants, grants as grants2
    Where
        grants.GrantID IN (*A 
                                         couple 
                                           Thousand
                                              keys*)
            and grants.GrantID = gracit_g.GrantID and grants2.GrantID = CitedID 
    LIMIT 500000) tbl1,
             grants, assignee_g, inventor_g, usclass_g, intclass_g
WHERE
    grants.GrantID = tbl1.CitingID
        and grants.GrantID = assignee_g.GrantID
        and grants.GrantID = inventor_g.GrantID
        and grants.GrantID = usclass_g.GrantID
        and grants.GrantID = intclass_g.GrantID
GROUP BY PN, GrantID
LIMIT 50000000

かなり 特許ごとに 後続の特許に引用されている 引用している特許の情報を記録したい。私が遭遇しているように見える問題は、私の「GROUP BY PN、GrantID」が「Using Temporary、Using Filesort」を引き起こし、私の努力を大幅に遅らせていることです。

これは私の説明が私に与えたものです(完全にフォーマットされていない場合は申し訳ありません。表の作成方法が見つかりませんでした)

1
PRIMARY派生2 ALL
8716 可能なキー: null キー: null key_len : null ref: null 一時的な使用; ファイルソートの使用







1
PRIMARY
付与
eq_ref
PRIMARY
PRIMARY
62
tbl1.CitingID
1


1
PRIMARY
assignee_g
ref
PRIMARY,FK_PublicationID_PUBLICATION_ASSIGNEE_P
PRIMARY
62
tbl1.CitingID
1


1
PRIMARY
intclass_g
ref
PRIMARY,fk_publicationid_PUBLICATION_INTERNATIONALCLASS_P
PRIMARY
62
tbl1.CitingID
1


1
PRIMARY
発明者_g
参照
PRIMARY,fk_PublicationID_Inventor_p
PRIMARY
62
tbl1.CitingID
1


1
PRIMARY
usclass_g
ref
PRIMARY,fk_publicationid_PUBLICATION_USCLASS_P
PRIMARY
62
tbl1.CitingID
2


2
DERIVED
付与
範囲
PRIMARY
PRIMARY
62
ref: null
2179
where; の使用。インデックスの使用


2
派生した
gracit_g
ref
PRIMARY,FK_PublicationID_PUBLICATION_PCITATION_P,CitedID
PRIMARY
62
uspto_patents.grants.GrantID
4
where の使用


2
DERIVED
grants2
eq_ref
PRIMARY
PRIMARY
62
uspto_patents.gracit_g.CitedID
1


gracit_g の SHOW CREATE は次のとおりです。

CREATE TABLE `gracit_g` (
`GrantID` varchar(20) NOT NULL,
`Position` int(11) NOT NULL,
`CitedID` varchar(20) DEFAULT NULL,
`Kind` varchar(10) DEFAULT NULL COMMENT 'identify whether citedDoc is a document or foreign patent',
`Name` varchar(100) DEFAULT NULL,
`Date` date DEFAULT NULL,
`Country` varchar(100) DEFAULT NULL,
`Category` varchar(100) DEFAULT NULL,
PRIMARY KEY (`GrantID`,`Position`),
KEY `FK_PublicationID_PUBLICATION_PCITATION_P` (`GrantID`),
KEY `CitedID` (`CitedID`),
CONSTRAINT `FK_GrantID_GRANT_PCITATION_G0` FOREIGN KEY (`GrantID`) REFERENCES `grants`   (`GrantID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8

付与の SHOW CREATE は次のとおりです。

 CREATE TABLE `grants` (
 `GrantID` varchar(20) NOT NULL,
 `Title` varchar(500) DEFAULT NULL,
 `IssueDate` date DEFAULT NULL,
 `Kind` varchar(2) DEFAULT NULL,
 `USSeriesCode` varchar(2) DEFAULT NULL,
 `Abstract` text,
 `ClaimsNum` int(11) DEFAULT NULL,
 `DrawingsNum` int(11) DEFAULT NULL,
 `FiguresNum` int(11) DEFAULT NULL,
 `ApplicationID` varchar(20) NOT NULL,
 `Claims` text,
 `FileDate` date DEFAULT NULL,
 `AppType` varchar(45) DEFAULT NULL,
 `AppNoOrig` varchar(10) DEFAULT NULL,
 `SourceName` varchar(100) DEFAULT NULL,
 PRIMARY KEY (`GrantID`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8

お時間をいただき、誠にありがとうございます。残念ながら、今のところ作業を続けるには遅すぎる(またはこの時点では早い)ため、ベッドに引退する必要があります)



1 つの提案は、サブクエリを使用する代わりに、1 つのクエリに変更することでした。

  SELECT 
        gracit_g.citedID,
        info_grant.GrantID,
        info_grant.FileDate,
        info_grant.IssueDate,
        info_grant.Kind,
        info_grant.ApplicationID,
        assignee_g.OrgName,
        GROUP_CONCAT(DISTINCT CONCAT_WS(', ', assignee_g.City, assignee_g.State, assignee_g.Country) separator ';') as Assignee,
        GROUP_CONCAT(DISTINCT CONCAT_WS(', ', inventor_g.FirstName, inventor_g.LastName) separator ';') as Inventor,
        GROUP_CONCAT(DISTINCT CONCAT_WS(', ', inventor_g.City, inventor_g.State, inventor_g.Country) separator ';') as Inventor_address,
        GROUP_CONCAT(DISTINCT CONCAT_WS(', ', usclass_g.Class, usclass_g.Subclass) separator ';') as USClass,
        intclass_g.Section,
        intclass_g.Class,
        intclass_g.Subclass,
        intclass_g.MainGroup,
        intclass_g.SubGroup
FROM
    gracit_g, grants as info_grant, assignee_g, inventor_g, usclass_g, intclass_g
WHERE
        gracit_g.GrantID IN (*KEYS*)
        and info_grant.GrantID = gracit_g.GrantID
        and info_grant.GrantID = assignee_g.GrantID
        and info_grant.GrantID = inventor_g.GrantID
        and info_grant.GrantID = usclass_g.GrantID
        and info_grant.GrantID = intclass_g.GrantID
GROUP BY gracit_g.citedID, info_grant.GrantID
LIMIT 50000000

これにより、21 秒の持続時間/10 秒のフェッチから 13 秒の持続時間/8 秒のフェッチに短縮されました。これは、通過するキーがたくさんあるため、まだ改善したいと考えています。

4

1 に答える 1

2

クエリは次の形式です。

SELECT some_fields
FROM (
    SELECT other_fields
    FROM table1, table2
    WHERE join_condition_table1_table2 AND some_other_condition
) AS subquery, table3
WHERE join_condition_subquery_table3
GROUP BY another_field

次のように書き直す必要があります。

SELECT some_fields
FROM table1, table2, table3
WHERE
    join_condition_table1_table2
    AND join_condition_subquery_table3 -- actually rewrite this ans a join of either table1 and table3, or table2 and table3
    AND some_other_condition
GROUP BY another_field

@Ollie Jones が指摘したように、条件SELECTの一部でもなく、集計関数内でもないフィールド (句内)を選択するのは危険です。GROUP BYこれらのフィールドが条件内のフィールドに一意に依存しない場合、これらのフィールドGROUP BYの値は未定義です。

[編集]

さらにいくつかの提案:

  • gracit_g(citedID, GrantID)この順序 ( ) でインデックスを追加し、句を にALTER TABLE gracit_g ADD INDEX(citedID, GrantID);変更します。オプティマイザは、このインデックスを使用して句を計算することを好みます。GROUP BYGROUP BY gracit_g.citedID, gracit_g.GrantIDGROUP BY

  • VARCHAR主キーが実際に数値である場合は、その型を適切な整数型に変更してください。そうでない場合は、数値の代理キーを追加し、それを主キーとして使用します。整数比較ははるかに高速であり、すべての結合で多くの比較を行います。

  • CONCAT_WS(', ', assignee_g.City, assignee_g.State, assignee_g.Country) separator ';')追加の列または追加のテーブルのように、連結された値を事前計算します (後者の場合、テーブルごとに追加の結合が必要になります)。

  • tmp_table_sizeおよびmax_heap_table_sizeサーバー オプションを増やします。一時テーブルがこれら 2 つの値 (バイト単位) のいずれかよりも大きくなると、一時テーブルをメモリに保持できなくなり、ディスクに書き込まれます。異常に大きな結果セットを扱っているため、ここで異常に大きな値を使用することでメリットが得られる場合があります。

他にやるべきことがあるかどうかはわかりません。より小さな結果セット (より少ない列、より多くのフィルター、またはより小さなLIMIT) を返すことを検討する必要がある場合があります。

于 2013-06-17T14:00:39.203 に答える