sql >> データベース >  >> RDS >> Mysql

DBクエリ時間の追跡-Bookshelf/knex

    knexを使用してトランザクション期間を追跡する方法をいくつか小さなテストコードで記述しました。

    https://runkit.com/embed/679qu91ylu4w

    /**
     * Calculate transaction durations in knex
     * 
     */
    require('sqlite3');
    var knex = require("knex")({
      client: 'sqlite', 
      connection: ':memory:', 
      pool: { min: 1, max: 10 }
    });
    
    function isTransactionStart(querySpec) {
      return querySpec.sql === 'BEGIN;';
    }
    
    function isTransactionEnd(querySpec) {
      return querySpec.sql === 'COMMIT;' || querySpec.sql === 'ROLLBACK;';
    }
    
    const transactionDurations = {};
    
    knex.on('query', querySpec => {
      console.log('On query', querySpec);
    
      if (isTransactionStart(querySpec)) {
        if (transactionDurations[querySpec.__knexUid]) {
          console.error('New transaction started, before earlier was ended');
          return;
        }
        transactionDurations[querySpec.__knexUid] = new Date().getTime();
      }
    
      if (isTransactionEnd(querySpec)) {
        const startTime = transactionDurations[querySpec.__knexUid];
        if (!startTime) {
          console.error('Transaction end detected, but start time not found');
        }
        const endTime = new Date().getTime();
        transactionDurations[querySpec.__knexUid] = null;
        console.log('TRANSACTION DURATION', endTime - startTime);
      }
    }); 
    
    // just as an example of other available events to show when they are called
    knex.on('query-response', (res, querySpec) => {
      // console.log('On query response', res, querySpec);
    }); 
    
    knex.on('query-error', (err, querySpec) => {
      // console.log('On query error', err, querySpec);
    }); 
    
    try {
        a = await Promise.all([
          knex.transaction(trx => {
            return trx.raw('select 1');
          }),
          knex.transaction(trx => {
            return trx.raw('select 2');
          }),
          knex.transaction(trx => {
            return trx.raw('error me');
          })
        ]);
    } catch (e) {
      console.log('Got ERROR:', e);
    }
    

    同じアプローチの王様は、クエリのタイミングにも機能するはずです。ただし、タイマーの簿記でメモリリークが発生しないようにするには、クリーンアップコードを追加する必要があります。

    クエリ期間タイマーはqueryで開始する必要があります イベントが発生し、query-responseで停止しました またはquery-error どちらが最初にトリガーするかによって異なります。

    queryと一致できるようにするため -query-response ペアquerySpec.__knexQueryUid 属性を使用できます。




    1. ms-sql2000のwhere句でAlias列を使用する

    2. mysqlsprocのテーブル名に変数を使用する

    3. OracleCONNECTBYとの混同

    4. SQLiteReadOnlyDatabaseException:読み取り専用データベースを書き込もうとしました(コード1032)