Есть ли способ удалить счетчик выбора (*) из этого оператора SQL и логики

0

У меня есть код C++, который обновляет столбец, когда строка существует, иначе ничего не делает. вот как выглядит мой код сейчас, а счетчик выбора (*) занимает около 15-20 секунд. я хотел бы сделать этот код более эффективным.

RunUpdateLockAliveTimeStamp

  sCommand << "update APP_CC_LOCKS set ALIVETIMESTAMP = ";
  sCommand << " SYSTIMESTAMP(7)";
  sCommand << " where TRANSACTIONID = ?";

RunSelectCountDataCubeLock

  sCommand << "select count(*) from APP_CC_LOCKS";
  sCommand << " where (((SCENARIOID=? and YEARID=? and ENTITYID=? and PARENTID=? and VALUEID=?) and (LOCKTYPE = ?)) or (LOCKTYPE = ?)) and (TRANSACTIONID != ?) and ((TIMEINSERTED < (select MAX(TIMEINSERTED) from APP_CC_LOCKS ";
  sCommand << " where TRANSACTIONID = ?)) or ((TIMEINSERTED = (select MAX(TIMEINSERTED) from ";
  sCommand << " APP_CC_LOCKS where TRANSACTIONID = ?)) and TRANSACTIONID <= ?))";

Главный

        DWORD dwIterationNumber = 0;

        // trying to accquire lock
        cStartTime = DateTimeUtil::currentDateTimeAsMilliseconds();

        while (bLockWasAcquired == false)
        {
              // try to accquire lock
              numBlockingRecords = -1;

              hr = cAccessor.RunSelectCountDataCubeLock(csTransID, lScenario, lYear, lEntity, lParent, lValue, &numBlockingRecords);
              xfm_throw_propagate(FAILED(hr), hr);

              // There no block record then lock is temporary accquired until we resolve collision
              if (numBlockingRecords == 0)
              {
                    // The lock is now accquired
                    bLockWasAcquired = true;
                    break;
              }

              if (dwIterationNumber > g_lNumIterBeforeUpdatingTimeStamp)
              {
                    //csSQLCmd.clear();
                    hr = cAccessor.RunUpdateLockAliveTimeStamp(csTransID);
                    xfm_throw_propagate(FAILED(hr), hr);
              }
        }
  • 1
    Вы можете, вероятно, создать запрос, который занимает меньше времени. Пожалуйста, измените ваш вопрос, опишите, что делает запрос, и покажите полный запрос в вопросе.
  • 0
    Согласитесь, хороший форматированный SQL-запрос, а не некоторые команды конкатенации строк будет легче читать.
Показать ещё 1 комментарий
Теги:
performance

1 ответ

2

Я не думаю, что count(*) - это то, что делает запрос медленным, а два подбора выбираются внутри предложения where.

...((TIMEINSERTED < (select MAX(TIMEINSERTED) from APP_CC_LOCKS where TRANSACTIONID = ?))    
or ((TIMEINSERTED = (select MAX(TIMEINSERTED) from APP_CC_LOCKS where TRANSACTIONID = ?))

может быть заменен одним подбором:

((TIMEINSERTED <= (select MAX(TIMEINSERTED) from APP_CC_LOCKS where TRANSACTIONID = ?))

что, вероятно, будет половину времени выполнения.

  • 2
    Всего одно очко - нет, count(col) не более эффективен, чем count(*) . Значение * in count(*) не означает «все столбцы», как select * . Знак * in count(*) означает «считать все строки», где count(col) означает «считать строки, где col не равно нулю», а count(1) означает «считать строки, где литерал 1 не равен нулю». Лучший способ и большинство самодокументируемых - это делать count(*) как он сообщает оптимизатору и всем, кто читает код, что вы хотите «посчитать все строки».
  • 0
    @KimBergHansen спасибо за эту очень полезную информацию. Наверное, я просто перепутал рекомендации не делать ненужного select * с помощью count(*) . Отредактировал мой ответ соответственно.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню