2017-01-14 1 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를 캐싱하지 않는다는 것을 의미하는 "Preparing statement ..."메시지를 로그에 표시한다! 어떻게하면 캐시를 매끄럽게 지시해야합니까?

다음 코드를 실행하면 PS가 캐시되지 않아야합니까? 내가 사용 컴파일 된 쿼리 @의 파블의 제안에 따라 다음과 같은 시도

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

: 다음과 같이

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

슬릭 설정이다에서

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

당신이 추가 JDBC 플래그를 설정해야 useServerPrepStmts=true MySQL을위한 몇 가지 간단한 performance tuning 구성 옵션을 제공하는 매우 유용한 문서에 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에 대해 설정 한 내용과 서버로드에 따라 메모리 사용량이 서버 및 클라이언트에서 모두 증가합니다 (예 : 최대 수명 연결을 MySQL 기본값 인 8 시간 미만으로 설정하면 서버와 클라이언트 모두 N 준비 상태가됩니다. 각 연결의 수명 동안 메모리에 살아있는 문장).

p.s.궁금하다면 병목 현상은 실제로 성명 캐싱 또는 Slick에 특정한 것입니다.

편집

로그 문은 쿼리 로그를 할 수 있습니다. MySQL의 5.7에 당신은 당신의 my.cnf에 추가합니다 :

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

및 mysqld를 다시 시작 다음에 다음 sudo touch /var/log/mysqlgeneral.log을. 구성 행 위에 주석을 달고 쿼리 로깅을 끄려면 다시 시작하십시오.

+0

답변 해 주셔서 감사합니다. 현재 준비된 문장 캐싱이 Slick + Hikari 콤보에서 전혀 작동하지 않는지에 대해 나는 궁금하다. JDBC에서 preparestatement가 캐쉬되어 있는지 아닌지 어떻게 확인할 수 있습니까? 서버 측 명령문 캐싱을 사용하는 – Richeek

+0

mysql 쿼리 로그는 초기 쿼리에 대해 하나의 prepare + execute를 표시하고 그 다음에 대상 명령문에 대한 모든 후속 캐시 히트에 대해서만 실행합니다. 'useServerPrepStmts = true'를 추가하면 로그에이 패턴이 표시됩니다. – virtualeyes

+0

나는 그것을 시험해 보았다. 실제로 당신은 어떻게 MySQL 쿼리 로깅을 켤 수 있는지 알고 있습니까? 나는 매끄러운 로깅을 켜 놓았고 항상 Prepear statement : select ...를 보여 주었다. 이 문장은 JdbcBackend.scala에서 가져온 것입니다 : https://github.com/slick/slick/blob/074002eb6290c0742ab28135c8109b3465311b81/slick/src/main/scala/slick/jdbc/JdbcBackend.scala#L301 그래서 혼동이 생깁니다 – Richeek

2

Compiled 개의 검색어를 사용해야합니다. 원하는 검색어를 정확하게 입력해야합니다. (당신이 일반적으로 PreparedStatement의 일부 매개 변수를 변경하려는 때문에)

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 이상 추출하지만 확실히 옵션 부분 :

그냥에 위의 코드를 변경합니다. 당신이 참조 할 수 있습니다 자세한 내용은

: MySQL을 들어 http://slick.lightbend.com/doc/3.1.0/queries.html#compiled-queries

+0

아하! 그걸 확인하고 다시 연락하게 해줘. 이 매우 유용한 관찰을 가져 주셔서 감사합니다 :) 그런데 내 매끄러운 설정에 대한 의견이 있습니까? JDBC url을 지정했기 때문에'properties' 객체가 중복되어 있다고 생각합니까? – Richeek

+0

나는 그것이 작동하는지 확실하지 않다! 컴파일 된 쿼리를 사용하거나 사용하지 않고이 루프의 타이밍을 수행했으며 거의 ​​동일하게 나타납니다. 나는이 파일에서 오는'Preparing statement : select user_name, ... '메시지를 본다 : https://github.com/slick/slick/blob/074002eb6290c0742ab28135c8109b3465311b81/slick/src/main/scala/slick/jdbc/JdbcBackend.scala 준비된 문장이 실제로 재사용되고 있는지 어떻게 확인할 수 있습니까? – Richeek

+0

당신은'def compiledQuery'가 아니라'val compiledQuery'를 가지고 계실 겁니다? –