Я помещаю превосходный ответ JLBorges на аналогичный вопрос дословно из cplusplus.com, так как это наиболее краткое объяснение, которое я прочитал по этому вопросу.
] В шаблоне, который мы пишем, есть два типа имен, которые можно использовать - зависимые имена и не зависимые имена. Зависимое имя - это имя, которое зависит от параметра шаблона; неизменяемое имя имеет то же значение, независимо от параметров шаблона.
Например:
template< typename T > void foo( T& x, std::string str, int count ) { // these names are looked up during the second phase // when foo is instantiated and the type T is known x.size(); // dependant name (non-type) T::instance_count ; // dependant name (non-type) typename T::iterator i ; // dependant name (type) // during the first phase, // T::instance_count is treated as a non-type (this is the default) // the typename keyword specifies that T::iterator is to be treated as a type. // these names are looked up during the first phase std::string::size_type s ; // non-dependant name (type) std::string::npos ; // non-dependant name (non-type) str.empty() ; // non-dependant name (non-type) count ; // non-dependant name (non-type) }
То, что зависит от зависимого имени, может быть чем-то другим для каждого конкретного экземпляра шаблона. Как следствие, шаблоны C ++ подвержены «двухфазному поиску имен». Когда шаблон сначала анализируется (до того, как выполняется какое-либо создание), компилятор просматривает не зависящие имена. Когда происходит конкретное создание шаблона, параметры шаблона известны к тому времени, и компилятор ищет зависимые имена.
На первом этапе анализатор должен знать, является ли зависимое имя именем типа или имени не-типа. По умолчанию зависимым именем считается имя не-типа.
Использовать ключевое слово typename только в объявлениях шаблонов и определениях, приведенных ниже.
blockquote>у вас есть квалифицированное имя, которое относится к типу и зависит от параметра шаблона.
Как я описываю на моем блоге , MySQL имеет функцию, названную SQL_CALC_FOUND_ROWS. Это устраняет необходимость сделать запрос дважды, но это все еще должно сделать запрос в своем entireity, даже если предельный пункт позволил бы ему останавливаться рано.
, Насколько я знаю, нет никакой подобной функции PostgreSQL. Одна вещь не упустить при выполнении разбиения на страницы (наиболее распространенная вещь, для которой ПРЕДЕЛ используется, по моему скромному мнению): выполнение "СМЕЩЕНИЯ, 1 000 ПРЕДЕЛОВ 10" означают, что DB должен выбрать [по крайней мере 112] 1 010 строк, даже если это только дает Вам 10. Более производительный способ сделать состоит в том, чтобы помнить значение строки, которой Вы заказываете для предыдущей строки (1000-е в этом случае) и переписываете запрос как это: "... ГДЕ order_row> value_of_1000_th ОГРАНИЧИВАЮТ 10 дюймов. Преимущество состоит в том, что "order_row" по всей вероятности индексируется (в противном случае, Вы имеете, идут проблема). Недостаток, являющийся, что, если новые элементы добавляются между просмотрами страницы, это может вытащить немного из синхронизации (но с другой стороны, это не может быть заметно посетителями и может быть большим увеличением производительности).
Вы могли смягчить потерю производительности, не выполнив КОЛИЧЕСТВО (), запрашивают каждый раз. Кэшируйте число страниц для, скажите за 5 минут до того, как запрос выполняется снова. Если Вы не видите огромное количество ВСТАВОК, которые должны работать просто великолепно.
Наблюдение, как необходимо знать в целях подкачки страниц, я предложил бы выполнить полный запрос однажды, пишущий данные в диск как кэш серверной стороны, затем подав это через механизм подкачки страниц.
при выполнении запроса КОЛИЧЕСТВА в целях решения, предоставить ли данные пользователю или не (т.е. если существует> X записей, отдайте ошибку), необходимо придерживаться подхода КОЛИЧЕСТВА.
Поскольку Postgres уже выполняет определенное кеширование, этот тип метода не так неэффективно, как кажется. Это точно не удвоение времени выполнения. У нас есть таймеры, встроенные в наш уровень БД, так что я видел доказательства.