У меня есть код 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);
}
}
Я не думаю, что 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 = ?))
что, вероятно, будет половину времени выполнения.
count(col)
не более эффективен, чем count(*)
. Значение *
in count(*)
не означает «все столбцы», как select *
. Знак *
in count(*)
означает «считать все строки», где count(col)
означает «считать строки, где col не равно нулю», а count(1)
означает «считать строки, где литерал 1 не равен нулю». Лучший способ и большинство самодокументируемых - это делать count(*)
как он сообщает оптимизатору и всем, кто читает код, что вы хотите «посчитать все строки».
select *
с помощью count(*)
. Отредактировал мой ответ соответственно.