2017-01-14 5 views
2

私は高速化しようとしています "SELECT * FROM WHERE name =?" Playでのクエリの種類+スカラアプリ。私はPlay 2.4 + Scala 2.11 + play-slick-1.1.1パッケージを使用しています。このパッケージはSlick-3.1バージョンを使用しています。キャッシュスリックDBIOアクション

私の仮説は、slickがDBIOアクションからPrepared文を生成し、実行されるという仮説でした。だから私はそれらをキャッシュしようとしましたcachePrepStmts = true しかし、私はまだ準備中の文を見る...というメッセージがログに記録されているので、PSはキャッシュされません。誰かがそれらをキャッシュするにはどのように滑らかに指示すべきですか?

次のコードを実行すると、PSがある時点でキャッシュされるべきではありませんか?

for (i <- 1 until 100) { 
    Await.result(db.run(doctorsTable.filter(_.userName === name).result), 10 seconds) 
} 

次のようにスリック設定は次のとおりです。

slick.dbs.default { 
    driver="slick.driver.MySQLDriver$" 
    db { 
    driver="com.mysql.jdbc.Driver" 

    url="jdbc:mysql://localhost:3306/staging_db?useSSL=false&cachePrepStmts=true" 

    user = "user" 

    password = "passwd" 

    numThreads = 1 // For not just one thread in HikariCP 

    properties = { 
     cachePrepStmts = true 
     prepStmtCacheSize = 250 
     prepStmtCacheSqlLimit = 2048 
    } 
    } 

} 

アップデート1

私がコンパイルされたクエリを使用しての@のパヴェルの提案に従って、次の試してみました。私の中

val compiledQuery = Compiled { name: Rep[String] => 
    doctorsTable.filter(_.userName === name) 
} 


val stTime = TimeUtil.getUtcTime 
for (i <- 1 until 100) { 
    FutureUtils.blockFuture(db.compiledQuery(name).result), 10) 
} 
val endTime = TimeUtil.getUtcTime - stTime 
Logger.info(s"Time Taken HERE $endTime") 

ログ私はまだ文のように表示されます:

2017-01-16 21:34:00,510 DEBUG [db-1] s.j.J.statement [?:?] Preparing statement: select ... 

このタイミングも同じです。希望の出力は何ですか?私はこれらの声明をもう見ないべきですか? Preparedステートメントが実際に再利用されたかどうかを確認する方法を教えてください。

答えて

1

、MySQLのためのいくつかの簡単なperformance tuningの構成オプションを提供し、非常に便利な文書へuseServerPrepStmts=true

HikariCPのMySQL configuration pageリンク:あなたはを参照することができ、さらに情報について

jdbc。

私は有用であることがわかりました(光のAPIで公開されていないオプションについては、&をjdbc urlに追加する必要があります)。各オプションについて、リンクされたドキュメントやMySQLのドキュメントを必ず読んでください。 が大部分はで安全です。

zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8 
rewriteBatchedStatements=true 
maintainTimeStats=false 
cacheServerConfiguration=true 
avoidCheckOnDuplicateKeyUpdateInSQL=true 
dontTrackOpenResources=true 
useLocalSessionState=true 
cachePrepStmts=true 
useServerPrepStmts=true 
prepStmtCacheSize=500 
prepStmtCacheSqlLimit=2048 

また、ステートメントはスレッドごとにキャッシュされます。あなたが光の接続maxLifetimeの設定に応じて、サーバの負荷がどのくらいであるかに応じて、サーバとクライアントの両方でメモリ使用量が増加します(たとえば、max max lifetimeをmysqlのデフォルトの8時間に設定した場合、各接続の寿命の間、メモリに記憶されたステートメント)。

p.s.ボトルネックが実際に文キャッシュかSlick特有のものかどうか不思議です。

EDIT

ログインするステートメントは、クエリのログを有効にします。 MySQLの5.7で、あなたのmy.cnfに追加します。mysqldを再起動するのに続いて

general-log=1 
general-log-file=/var/log/mysqlgeneral.log 

、その後sudo touch /var/log/mysqlgeneral.log。設定行の上にコメントアウトし、再起動してクエリのロギングを無効にします。

+0

お返事ありがとうございます。現時点では、準備されたステートメントキャッシングがSlick + Hikariのコンボではまったく動作しているかどうかに関しては全く興味がありません。私はpreparedstatementがキャッシュされているかどうかをどのように検証することができますか?サーバサイドの文キャッシュを有効にした – Richeek

+0

mysqlクエリログでは、最初のクエリに対して1回のprepare + executeが表示され、その後にターゲット文のそれ以降のすべてのキャッシュヒットに対してのみ実行されます。 'useServerPrepStmts = true'を追加すると、このパターンがログに表示されます。 – virtualeyes

+0

私はそれを試みました。実際にあなたはどのように私はMySQLのクエリのログを有効にすることができます知っていますか?私は滑らかなロギングをオンにし、常に準備中の文:選択...のような種類のログを表示します。このステートメントはJdbcBackend.scalaから来ています:https://github.com/slick/slick/blob/074002eb6290c0742ab28135c8109b3465311b81/slick/src/main/scala/slick/jdbc/JdbcBackend.scala#L301それで混乱が生まれます – Richeek

2

Compiledクエリを使用する必要があります。これは正確にあなたが望むことを実行しています。

ちょうどに上記のコード変更:

val compiledQuery = Compiled { name: Rep[String] => 
    doctorsTable.filter(_.userName === name) 
} 

for (i <- 1 until 100) { 
    Await.result(db.run(compiledQuery(name).result), 10 seconds) 
} 

私は、パラメータとしてname上で抽出された(あなたは通常、あなたのPreparedStatement s内のいくつかのパラメータを変更したいので)それは間違いなく、オプションの一部です。あなたは追加のJDBCフラグを設定する必要がMySQLの場合http://slick.lightbend.com/doc/3.1.0/queries.html#compiled-queries

+0

Aha!私はそれを確認して、あなたに戻ってみましょう。この非常に有用な観測をありがとう:)ところで、あなたは私の滑らかな設定についてのコメントがありますか? JDBC urlを指定しているので、 'properties'オブジェクトは冗長であると思いますか? – Richeek

+0

私はそれが働いているかわからない!私はコンパイルされたクエリの有無にかかわらずこのループのタイミングを実行し、ほぼ同じになります。私はこのファイルから来る '準備文:select user_name、...'メッセージを見ています:https://github.com/slick/slick/blob/074002eb6290c0742ab28135c8109b3465311b81/slick/src/main/scala/slick/jdbc/JdbcBackend.scala準備されたステートメントが実際に再利用されていることを確認するにはどうすればよいですか? – Richeek

+0

あなたは 'def compiledQuery'ではなく' val compiledQuery'を持っていますか? –