Используйте стек, когда используемая память строго ограничена объемом, в котором Вы создаете его. Это полезно для предотвращения утечек памяти, потому что Вы знаете точно, где Вы хотите использовать память, и Вы знаете, когда Вам больше не нужна она, таким образом, память будет очищена для Вас.
int main()
{
if (...)
{
int i = 0;
}
// I know that i is no longer needed here, so declaring i in the above block
// limits the scope appropriately
}
"куча", однако, полезна, когда к Вашей памяти можно получить доступ за пределами объема ее создания, и Вы не хотите копировать переменную стека. Это может дать Вам явный контроль над тем, как память выделена и освобождена.
Object* CreateObject();
int main()
{
Object* obj = CreateObject();
// I can continue to manipulate object and I decide when I'm done with it
// ..
// I'm done
delete obj;
// .. keep going if you wish
return 0;
}
Object* CreateObject()
{
Object* returnValue = new Object();
// ... do a bunch of stuff to returnValue
return returnValue;
// Note the object created via new here doesn't go away, its passed back using
// a pointer
}
, Очевидно, типичная проблема здесь состоит в том, что можно забыть удалять объект. Это называют утечкой памяти. Эти проблемы более распространены, поскольку Ваша программа становится все меньше и меньше тривиальной, где "владение" (или кто точно ответственен за удаление вещей) становится более трудным определить.
Общие решения на более управляемых языках (C#, Java) должны реализовать сборку "мусора", таким образом, Вы не должны думать об удалении вещей. Однако это означает, что существует что-то в фоновом режиме, которое работает апериодическим образом для проверения данных "кучи". В нетривиальной программе это может стать довольно неэффективным, поскольку поток "сборки"мусора"" открывается и двигается с пыхтением далеко, ища данные, которые должны быть удалены, в то время как остальная часть Вашей программы заблокирована от выполнения.
В C++, наиболее распространенном, и лучше всего (по-моему), решение контакта с утечками памяти состоит в том, чтобы использовать интеллектуальный указатель. Наиболее распространенный из них повышение:: shared_ptr, который является ( ссылка рассчитала )
Так для воссоздания примера выше повышения:: shared_ptr CreateObject ();
int main()
{
boost::shared_ptr
This is normal. Index will only be used if you have a '=' condition. Searching index for != condition is not effective.
Similarly, this may use the index (in Oracle)
select * from Table where x like 'some%'
but this wouldn't
select * from Table where x like '%thing%'
Also,
выберите * из таблицы, где x от 1 до 10
будет использовать индекс
, но не
select * from Table where x not between 1 and 10
this is absolutely normal. index is used to look for exact something. where you start when I ask you to look a dictionary when I told you not start with 'S'.
you can always do this.
select * from Table a
where not exist (select * from table b where x = 'somestring' and a.key = b.key)
That is indeed normal - to use the index, you need to use a exact match (like the "=" equals operator), or something like a range query.
A query that defines a "negative" criteria (NOT something or another) typically can't be satisfied by an index lookup - you'll have to look up everything except a certain value. That doesn't work nicely - typically, a full table scan (clustered index scan in SQL Server) will be quicker, just checking for the criteria to be matched (or not matched, in that case).
You didn't say what database engine you are using.
MS SQL Server, for example, has both Equality indexes
and Inequality indexes
.
The latter are used when the not equal
operator is in play.
Я думаю, что условие! = Может использовать индекс (в MSSQL). Согласно плану выполнения в MSSQL, если у меня есть индекс для одного поля, и я применяю предложение where к этому полю, одно с! = И одно с =, они оба приводят к одному и тому же плану выполнения, оба с использованием индекса искать.
Он может использовать индекс, если индекс является кластеризованным и существует не так много разных значений индексированного атрибута (поэтому мы можем быстро решить, какие блоки мы можем пропустить). Но если индексированный атрибут, скажем, является ключом, то использование индекса в этом случае не имеет абсолютно никакого смысла.