2012-04-05 113 views
1

下面是背景,我有一個API方法,它向我的服務器發送一個規範化的名稱列表,然後匹配給定的Persons對象的名稱。每個人都有許多與他們相關的Post對象,我想返回。我的數據庫查詢看起來是這樣的:Rails優化複雜查詢

@articles = Article.joins(:artists).select("artists.*").where({:artists=>{:name=>keys}}).group("#{Article.col_list}").order("articles.publish_date DESC").limit(25) 

這種查詢可以把我的生產服務器上只要2秒的時候名稱的列表很大(超過100)。我怎樣才能優化這個查詢,使其快速?

這是查詢的EXPLAIN。

Limit (cost=9144.19..9144.20 rows=25 width=802) (actual time=4341.409..4341.431 rows=25 loops=1) 
    -> Sort (cost=9144.19..9150.74 rows=13096 width=802) (actual time=4341.408..4341.416 rows=25 loops=1) 
     Sort Key: articles.publish_date 
     Sort Method: top-N heapsort Memory: 47kB 
     -> HashAggregate (cost=9030.99..9070.28 rows=13096 width=802) (actual time=4255.854..4315.125 rows=3916 loops=1) 
       -> Nested Loop (cost=1581.27..8978.60 rows=13096 width=802) (actual time=7.443..3337.624 rows=39920 loops=1) 
        -> Hash Join (cost=1581.27..7650.04 rows=13096 width=4) (actual time=7.426..2627.426 rows=39920 loops=1) 
          Hash Cond: (articles_artists.artist_id = artists.id) 
          -> Seq Scan on articles_artists (cost=0.00..5476.38 rows=737461 width=8) (actual time=0.019..1310.806 rows=737515 loops=1) 
          -> Hash (cost=1579.83..1579.83 rows=413 width=4) (actual time=7.383..7.383 rows=300 loops=1) 
           Buckets: 1024 Batches: 1 Memory Usage: 8kB 
           -> Bitmap Heap Scan on artists (cost=477.60..1579.83 rows=413 width=4) (actual time=4.959..7.152 rows=300 loops=1) 
             Recheck Cond: ((name)::text = ANY ('{"A BOY NAMED EARTH","A ROCKET TO MOON","A SKYLIT DRIVE","A VISIBLE BOY","AARON GILLESPIE",AB,"ABBIE BARRETT",ABERFELDY,"ABRA NIIRE","ABSOLUTE ZERO",ACDC,"ADAM GREEN",ADELE,ADO,"ADRINA THORPE",ADVENTURE,AEROSMITH,"AESOP ROCK",AFI,AIR,"AIR TRAFFIC",AKON,"AL GREEN","ALANIS MORISSETTE",ALCENDOR,"ALEX CHILTON","ALEXI MURDOCH","ALIAS EHREN","ALICE RUSSELL","ALICIA KEYS","AMANDA PALMER","AMERICAN FOOTBALL","AMY MACDONALD","AMY WINEHOUSE","ANALOG REBELLION",ANBERLIN,"ANDREW BIRD","ANDREW HILL","ANGELS AIRWAVES",AQUEDUCT,"ARCADE FIRE","ARETHA FRANKLIN","ART BRUT","ART GARFUNKEL","ARTIC MONKEYS","ARTIC MONKEYS","AS TALL AS LIONS",ASHANTI,"ATLAS SOUND","ATTACK ATTACK!",AUTOLUX,"AVENUE D","AVRIL LAVIGNE","B JU",BACK2SQUARE1,"BAD ENGLISH",BALMORHEA,"BAND OF HORSES",BARCELONA,"BAXTER DURY","BEASTIE BOYS",BEATLES,BECK,"BELLE AND SEBASTIAN","BEN FOLDS FIVE","BEN MARTIN","BETTE MIDLER","BETTIE SERVEERT",BEYONCE,"BIFFY CLYRO","BILLY BRAGG","BILLY BRAGG AND BLOKES","BILLY JOEL","BILLY OCEAN",BIRDY,"BLACK EYED PEAS","BLACK KIDS",BLACKSTONE,"BLIND PILOT","BLINK 182","BLOC PARTY","BLOODHOUND GANG",BLUEBOY,BLUR,"BOB DYLAN","BOB MARLEY","BOB MARLEY WAILERS","BOMBAY BICYCLE CLUB","BON IVER","BONNIE TYLER",BONOBO,"BOX CAR RACER","BOYS LIKE GIRLS","BOYZ II MEN",BREAKBOT,"BRENDAN BENSON","BRETT ANDERSON",BRICOLAGE,"BRITNEY SPEARS",BRONCO,"BRUCE SPRINGSTEEN","BRUNO MARS",BUSH,"BUSTA RHYMES",BUSTED,CAESARS,"CAGE ELEPHANT",CAKE,CALLA,"CALVIN HARRIS",CAMRON,CAMRON,CAMP,CAMPING,"CANDIE PAYNE",CASHEW,"CASSANDRA WILSOM",CASSIDY,"CATE LE BON","CHARLIE FEATHERS","CHERRY GHOST",CHIC,CHICAGO,CHINGY,"CHRIS BROWN","CHRISTINA AGUILERA","CHRISTINA STURMER",CHUMBAWAMBA,CIRCLE,"CLARENCE CARTER",CLIPSE,"COBRA STARSHIP",COLDPLAY,COMMON,CONSPIRATORS,COOLIO,COPELAND,"COPY HAHO",CORNELIUS,CREED,CULTS,"CYNDI LAUPER","CYPRESS HILL","CAT EMPIRE",CURE,"DA LATA","DAFT PUNK",DALMINJO,DAMERO,"DARREN HANLON","DASHBOARD CONFESSIONAL",DATAROCK,"DAVID BOWIE","DAVID E SUGAR","DAVID GUETTA","DAVID KITT","DEATH CAB FOR CUTIE","DIANA KRALL",DIGITALISM,"DINOSAUR JR","DISCO INFERNO",DISCOVERY,"DIZZEE RASCAL",DMX,"DON BLACKMAN","DR DOG",DRAKE,DRUGSTORE,DIPLOMATS,DREAM,EAGLES,EDITORS,ELBOW,ELECTRELANE,"ELIZA DOOLITTLE","ELLE MILANO","ELLIE GOULDING","ELTON JOHN","ELVIS COSTELLO WITH BURT BACHARACH","ELVIS PRESLEY",EMBRACE,EMINEM,"EMMY GREAT","EMPIRE! EMPIRE!","ERIC CHURCH","ERIC CLAPTON","ERIN MCCARLEY",ERRORS,"EUGENE KELLY","EXPLOSIONS IN SKY",FABOLOUS,FAILURE,"FAITH EVANS","FAR EAST MOVEMENT",FAUNTS,FEIST,FELT,FIELDS,"FLEET FOXES","FLIGHT OF CONCHORDS","FLORENCE MACHINE",FOALS,"FOO FIGHTERS","FOSTER PEOPLE","FOUR TET","FRANK TURNER","FRANZ FEDINAND",FREE,"FLAMING LIPS",GORILLAZ,"GRATEFUL DEAD",IDLEWILD,"IMANI COPPOLA","IMOGEN HEAP",INCUBUS,INCUBUS,"IRON WINE","J DILLA","J COLE",JACK,"JACK JOHNSON",JACOBITES,"JAMES BLAKE","JAMES BLUNT","JAMES BONG","JAMES BROWN","JAMIE T","JAN DELAY","JANE CULLUM","JASON DERULO","JASON MORAN","JAY Z","JAY Z","JEFF WAYNE","JENNIFER LOPEZ","JENNY LEWIS",JEREMIH,"JIM JONES","JIMMY EAT WORLD","JOHN COLTRANE","JOHN LEGEND","JOHN MAYER","JOY DIVISION","JUELZ SANTANA","JUNIOR BOYS","JUSTIN TIMBERLAKE","KAISER CHEIFS",KANTE,"KANYE WEST",KARMA,"KATE NASH","KATE NASH","KATY PERRY",KESHA,KEANE,KEANE,"KELLY ROWLAND","KENNY G","KERI HILSON","KEVIN AYERS","KID CUDI","KID HARPOON","KID LOCO","KID ROCK","KINGS OF LEON",KILLERS,KOOKS,"LADY GAGA","LADY SOVEREIGN","LED ZEPPELIN","LEE DORSEY",LEMAR,LEMONGRASS,"LEROY HUTSON","LIL WAYNE","LILY ALLEN","LITTLE COMETS","LITTLE JOY","LL COOL J",LLOYD,"LLOYD BANKS","LONDON LOUNGE",LOST,LOVE,LUDACRIS,LUDIQUE,"LUPE FIASCO","LUTHER VANDROS","MACHINE HEAD","MACY GRAY",MADONNA,MAINO,"MANU CHAO","MAREN MONTAUK","MARIAH CAREY","MARK FRY","MARK MORRISON","MARK RONSON","MAROON 5","MARY J BLIGE","MASSIVE ATTACK","MAT KEARNEY","MATTHEW DEAR","MEAT LOAF",METALLICA,MGMT,"MICHAEL GIACCHINO","MICHAEL JACKSON","MILES DAVIS","MISSY ELLIOTT","MOBB DEEP","MODEST MOUSE","MODEST MOUSE",MONK,MOON,MORRISSEY,MOTZ,"MOVING HEARTS",MUSE,MUTEMATH,"MY WRITES","MORNING OF",NAS,"NE YO","NICKI MINAJ","NINE INCH NAILS","P DIDDY","PATRICK WATSON","PAUL MCCARTNEY","PEARL JAM","PEPE ALGILAR","PEPE WHITE","PETER GABRIEL",PHARRELL,"PHIL COLLINS",PHISH,PITBULL,PIXIES,POLICE,PRINCE,"R KELLY",RADIOHEAD,RAKIM,RANK,"RASCAL FLATTS","RAY CHARLES","RED HOT CHILI PEPPERS",REDNEX,REENO,"RELIENT K","RICK ROSS","RICKY NELSON",RIFT,RIHANNA,"ROBBIE WILLIAMS","ROD STEWART","RODNEY HUNTER",ROKOKO,"ROLLING STONES","ROSCOE DASH","ROY DAVIS JR","RYAN LESLIE","RYAN LESLIE",RZA,"SARAH MCLACHLAN","SARAH RUSSELL",SEAL,"SHANIA TWAIN",SHERWOOD,"SMASH MOUTH",SMITHS,"SNOOP DOGG","SOMETHING CORPORATE",SPOON,SPOON,"ST LUNATICS",STARS,"STAT QUO","STEELY DAN","STEVIE WONDER","STYLES P","SUNSET RUBDOWN",SUPERCHUNK,"SWIZZ BEATZ","SECRET HANDSHAKE",SMITHS,"T PAIN",TI,"TALIB KWELI","TAYLOR SWIFT","THROWING MUSES",TLC,"TOM JONES","TOM PETTY","TONY YAYO",TOOL,"TORI AMOS",TORTOISE,TRAIN,"TREY SONGZ","TRIBE CALLED QUEST",TUBBS,TYCHO,"WHITE STRIPES","WAKA FLOCKA FLAME",WALE,WILCO,"WILL SMITH",U2,USHER,"YEAH YEAH YEAHS","YEAR OF RABBIT","YOUNG BUCK","YOUNG JEEZY","ZAC BROWN BAND",2PAC,"50 CENT"}'::text[])) 
             -> Bitmap Index Scan on index_artists_on_name (cost=0.00..477.58 rows=413 width=0) (actual time=4.897..4.897 rows=311 loops=1) 
              Index Cond: ((name)::text = ANY ('{"A BOY NAMED EARTH","A ROCKET TO MOON","A SKYLIT DRIVE","A VISIBLE BOY","AARON GILLESPIE",AB,"ABBIE BARRETT",ABERFELDY,"ABRA NIIRE","ABSOLUTE ZERO",ACDC,"ADAM GREEN",ADELE,ADO,"ADRINA THORPE",ADVENTURE,AEROSMITH,"AESOP ROCK",AFI,AIR,"AIR TRAFFIC",AKON,"AL GREEN","ALANIS MORISSETTE",ALCENDOR,"ALEX CHILTON","ALEXI MURDOCH","ALIAS EHREN","ALICE RUSSELL","ALICIA KEYS","AMANDA PALMER","AMERICAN FOOTBALL","AMY MACDONALD","AMY WINEHOUSE","ANALOG REBELLION",ANBERLIN,"ANDREW BIRD","ANDREW HILL","ANGELS AIRWAVES",AQUEDUCT,"ARCADE FIRE","ARETHA FRANKLIN","ART BRUT","ART GARFUNKEL","ARTIC MONKEYS","ARTIC MONKEYS","AS TALL AS LIONS",ASHANTI,"ATLAS SOUND","ATTACK ATTACK!",AUTOLUX,"AVENUE D","AVRIL LAVIGNE","B JU",BACK2SQUARE1,"BAD ENGLISH",BALMORHEA,"BAND OF HORSES",BARCELONA,"BAXTER DURY","BEASTIE BOYS",BEATLES,BECK,"BELLE AND SEBASTIAN","BEN FOLDS FIVE","BEN MARTIN","BETTE MIDLER","BETTIE SERVEERT",BEYONCE,"BIFFY CLYRO","BILLY BRAGG","BILLY BRAGG AND BLOKES","BILLY JOEL","BILLY OCEAN",BIRDY,"BLACK EYED PEAS","BLACK KIDS",BLACKSTONE,"BLIND PILOT","BLINK 182","BLOC PARTY","BLOODHOUND GANG",BLUEBOY,BLUR,"BOB DYLAN","BOB MARLEY","BOB MARLEY WAILERS","BOMBAY BICYCLE CLUB","BON IVER","BONNIE TYLER",BONOBO,"BOX CAR RACER","BOYS LIKE GIRLS","BOYZ II MEN",BREAKBOT,"BRENDAN BENSON","BRETT ANDERSON",BRICOLAGE,"BRITNEY SPEARS",BRONCO,"BRUCE SPRINGSTEEN","BRUNO MARS",BUSH,"BUSTA RHYMES",BUSTED,CAESARS,"CAGE ELEPHANT",CAKE,CALLA,"CALVIN HARRIS",CAMRON,CAMRON,CAMP,CAMPING,"CANDIE PAYNE",CASHEW,"CASSANDRA WILSOM",CASSIDY,"CATE LE BON","CHARLIE FEATHERS","CHERRY GHOST",CHIC,CHICAGO,CHINGY,"CHRIS BROWN","CHRISTINA AGUILERA","CHRISTINA STURMER",CHUMBAWAMBA,CIRCLE,"CLARENCE CARTER",CLIPSE,"COBRA STARSHIP",COLDPLAY,COMMON,CONSPIRATORS,COOLIO,COPELAND,"COPY HAHO",CORNELIUS,CREED,CULTS,"CYNDI LAUPER","CYPRESS HILL","CAT EMPIRE",CURE,"DA LATA","DAFT PUNK",DALMINJO,DAMERO,"DARREN HANLON","DASHBOARD CONFESSIONAL",DATAROCK,"DAVID BOWIE","DAVID E SUGAR","DAVID GUETTA","DAVID KITT","DEATH CAB FOR CUTIE","DIANA KRALL",DIGITALISM,"DINOSAUR JR","DISCO INFERNO",DISCOVERY,"DIZZEE RASCAL",DMX,"DON BLACKMAN","DR DOG",DRAKE,DRUGSTORE,DIPLOMATS,DREAM,EAGLES,EDITORS,ELBOW,ELECTRELANE,"ELIZA DOOLITTLE","ELLE MILANO","ELLIE GOULDING","ELTON JOHN","ELVIS COSTELLO WITH BURT BACHARACH","ELVIS PRESLEY",EMBRACE,EMINEM,"EMMY GREAT","EMPIRE! EMPIRE!","ERIC CHURCH","ERIC CLAPTON","ERIN MCCARLEY",ERRORS,"EUGENE KELLY","EXPLOSIONS IN SKY",FABOLOUS,FAILURE,"FAITH EVANS","FAR EAST MOVEMENT",FAUNTS,FEIST,FELT,FIELDS,"FLEET FOXES","FLIGHT OF CONCHORDS","FLORENCE MACHINE",FOALS,"FOO FIGHTERS","FOSTER PEOPLE","FOUR TET","FRANK TURNER","FRANZ FEDINAND",FREE,"FLAMING LIPS",GORILLAZ,"GRATEFUL DEAD",IDLEWILD,"IMANI COPPOLA","IMOGEN HEAP",INCUBUS,INCUBUS,"IRON WINE","J DILLA","J COLE",JACK,"JACK JOHNSON",JACOBITES,"JAMES BLAKE","JAMES BLUNT","JAMES BONG","JAMES BROWN","JAMIE T","JAN DELAY","JANE CULLUM","JASON DERULO","JASON MORAN","JAY Z","JAY Z","JEFF WAYNE","JENNIFER LOPEZ","JENNY LEWIS",JEREMIH,"JIM JONES","JIMMY EAT WORLD","JOHN COLTRANE","JOHN LEGEND","JOHN MAYER","JOY DIVISION","JUELZ SANTANA","JUNIOR BOYS","JUSTIN TIMBERLAKE","KAISER CHEIFS",KANTE,"KANYE WEST",KARMA,"KATE NASH","KATE NASH","KATY PERRY",KESHA,KEANE,KEANE,"KELLY ROWLAND","KENNY G","KERI HILSON","KEVIN AYERS","KID CUDI","KID HARPOON","KID LOCO","KID ROCK","KINGS OF LEON",KILLERS,KOOKS,"LADY GAGA","LADY SOVEREIGN","LED ZEPPELIN","LEE DORSEY",LEMAR,LEMONGRASS,"LEROY HUTSON","LIL WAYNE","LILY ALLEN","LITTLE COMETS","LITTLE JOY","LL COOL J",LLOYD,"LLOYD BANKS","LONDON LOUNGE",LOST,LOVE,LUDACRIS,LUDIQUE,"LUPE FIASCO","LUTHER VANDROS","MACHINE HEAD","MACY GRAY",MADONNA,MAINO,"MANU CHAO","MAREN MONTAUK","MARIAH CAREY","MARK FRY","MARK MORRISON","MARK RONSON","MAROON 5","MARY J BLIGE","MASSIVE ATTACK","MAT KEARNEY","MATTHEW DEAR","MEAT LOAF",METALLICA,MGMT,"MICHAEL GIACCHINO","MICHAEL JACKSON","MILES DAVIS","MISSY ELLIOTT","MOBB DEEP","MODEST MOUSE","MODEST MOUSE",MONK,MOON,MORRISSEY,MOTZ,"MOVING HEARTS",MUSE,MUTEMATH,"MY WRITES","MORNING OF",NAS,"NE YO","NICKI MINAJ","NINE INCH NAILS","P DIDDY","PATRICK WATSON","PAUL MCCARTNEY","PEARL JAM","PEPE ALGILAR","PEPE WHITE","PETER GABRIEL",PHARRELL,"PHIL COLLINS",PHISH,PITBULL,PIXIES,POLICE,PRINCE,"R KELLY",RADIOHEAD,RAKIM,RANK,"RASCAL FLATTS","RAY CHARLES","RED HOT CHILI PEPPERS",REDNEX,REENO,"RELIENT K","RICK ROSS","RICKY NELSON",RIFT,RIHANNA,"ROBBIE WILLIAMS","ROD STEWART","RODNEY HUNTER",ROKOKO,"ROLLING STONES","ROSCOE DASH","ROY DAVIS JR","RYAN LESLIE","RYAN LESLIE",RZA,"SARAH MCLACHLAN","SARAH RUSSELL",SEAL,"SHANIA TWAIN",SHERWOOD,"SMASH MOUTH",SMITHS,"SNOOP DOGG","SOMETHING CORPORATE",SPOON,SPOON,"ST LUNATICS",STARS,"STAT QUO","STEELY DAN","STEVIE WONDER","STYLES P","SUNSET RUBDOWN",SUPERCHUNK,"SWIZZ BEATZ","SECRET HANDSHAKE",SMITHS,"T PAIN",TI,"TALIB KWELI","TAYLOR SWIFT","THROWING MUSES",TLC,"TOM JONES","TOM PETTY","TONY YAYO",TOOL,"TORI AMOS",TORTOISE,TRAIN,"TREY SONGZ","TRIBE CALLED QUEST",TUBBS,TYCHO,"WHITE STRIPES","WAKA FLOCKA FLAME",WALE,WILCO,"WILL SMITH",U2,USHER,"YEAH YEAH YEAHS","YEAR OF RABBIT","YOUNG BUCK","YOUNG JEEZY","ZAC BROWN BAND",2PAC,"50 CENT"}'::text[])) 
        -> Index Scan using articles_pkey on articles (cost=0.00..0.10 rows=1 width=802) (actual time=0.006..0.006 rows=1 loops=39920) 
          Index Cond: (articles.id = articles_artists.article_id) 
Total runtime: 4343.603 ms 
(18 rows) 
+2

這實際上是一個數據庫優化問題。查看您的日誌文件以查找實際的SQL查詢,並通過「EXPLAIN」運行它。如果這不能指導您正確的方向,請將該信息添加到問題中。可能有一個索引缺少連接。 – Thilo 2012-04-05 15:50:45

+0

請發佈AR針對此查詢發出的實際SQL。你有關於articles_artists(artist_id)的索引嗎? – dbenhur 2012-04-05 19:36:22

回答

0

看起來你會抓住最近的25篇文章。所以我會使用一個子查詢來選擇最近的25篇文章,並將結果與​​藝術家表結合起來。

爲什麼這會更好?由於您的查詢建立一個臨時的結果是加入與他們所有的文章的每一個藝術家排序結果,並採取最近25

不......我錯了。我通過名字看到藝術家的位置,這意味着我的解決方案不會工作。

所以我回來看看我能不能幫忙。藝術家的名字'過濾器'是如果你看看你發佈的解釋數據的成本,那麼你花費的最多。還要注意藝術家的名字都出現在那裏,TWICE意味着你在嵌套循環中不止一次地爲這個操作付錢。

所以,如果可以的話,建立一個臨時表,它是通過你的過濾器的藝術家表。然後使用該表按照前面描述的方式執行文章查找,查詢速度會快得多。

+0

藝術家名稱過濾器需要7ms。最大的代價是在連接表articles_artists的seq掃描和針對藝術家過濾器中發現的藝術家的散列連接。請參閱http://explain.depesz.com/s/Az9x,以便更好地瞭解計劃並突出顯示昂貴的步驟。 – dbenhur 2012-04-06 00:54:29

+0

OP需要發佈查詢SQL,以便我們可以嘗試改進此計劃的方法。 – dbenhur 2012-04-06 00:55:23

1

這一個突出:

- > SEQ掃描上articles_artists(成本= 0.00..5476.38行= 737461寬度= 8)(實際時間= 0.019..1310.806行= 737515個循環= 1)

如果您在查詢上運行EXPLAIN,並在任何地方看到術語「Seq Scan」,則表示您需要檢查您是否擁有所有正確的索引。檢查articles_artists並確保您在article_idartist_id上都有索引,假設您已如此命名它們。

而且,你的數據庫上運行VACUUM ANALYZE,看看是否有加速的事情了。 Postgresql的查詢優化器依賴於VACUUM ANALYZE生成的統計信息,因此如果在沒有運行的情況下表格發生了顯着變化,查詢性能可能會受到影響。

最後,考慮打破了查詢並獲得Ruby收集數據。有時候最好不要試圖讓數據庫足夠聰明,以便正確執行復雜查詢,而是在客戶端手動優化它。

+0

但請注意,隨後的散列連接會獲得所選730K行的40K。選擇性爲12%時,seq掃描的順序IO完全有可能擊敗索引掃描的隨機查找IO。 – dbenhur 2012-04-06 17:28:44

+0

是的,這是真的。不想在我的回答中走得那麼遠:)這就是我說的「這是一個標誌」,「這意味着」需要更多的索引。 – 2012-04-06 17:32:57

0

我看到兩個問題。首先是Michele上面提到的seq掃描。第二個是嵌套循環連接,可能是由於該點發生的記錄太多。

我想看看,使盡可能少的項目被選爲可能的,你可以進一步推什麼下該查詢的搜索標準條款。

我的猜測是,指數不會有很大的差別,但附加的搜索條件會,特別是在這些可以打一個索引。