sqlite is a speedy database. But the words speedy,fast,peppy,or quick are rather subjective terms. To be
perfectly honest,there are things sqlite can do faster than other databases,and there are things that it
cannot. Suffice it to say,within the parameters for which it has been designed,sqlite can be said to be
consistently fast and efficient across the board. sqlite uses B-trees for indexes and B+-trees for tables,
the same as most other database systems. For searching a single table,it is as fast if not faster than any
other database on average. Simple SELECT,INSERT,and UPDATE statements are extremely quick—virtually
at the speed of RAM (for in-memory databases) or disk. Here sqlite is often faster than other databases,
because it has less overhead to deal with in starting a transaction or generating a query plan and because
it doesn’t incur the overhead of making a network calls to the server or negotiating authentication and
privileges. Its simplicity here makes it fast.
As queries become larger and more complex,however,query time overshadows the network call or
transaction overhead,and the game goes to the database with the best optimizer. This is where larger,
more sophisticated databases begin to shine. While sqlite can certainly do complex queries,it does not
have a sophisticated optimizer or query planner. You can always trust sqlite to give you the result,but
what it won’t do is try to determine optimal paths by computing millions of alternative query plans and
selecting the fastest candidate,as you might expect from Oracle or Postgresql. Thus,if you are running
complex queries on large data sets,odds are that sqlite is not going to be as fast as databases with
sophisticated optimizers.
So,there are situations where sqlite is not as fast as larger databases. But many if not all of these
conditions are to be expected. sqlite is an embedded database designed for small to medium-sized
applications. These limitations are in line with its intended purpose. Many new users make the mistake
of assuming that they can use sqlite as a drop-in replacement for larger relational databases.
Sometimes you can; sometimes you can’t. It all depends on what you are trying to do.
In general,there are two major variables that define sqlite’s main limitations:
•Concurrency(并发). sqlite has coarse-grained locking,which allows multiple readers
but only one writer at a time. Writers exclusively lock the database during writes,
and no one else has access during that time. sqlite does take steps to minimize
the amount of time in which exclusive locks are held. Generally,locks in sqlite
are kept for only a few milliseconds. But as a general rule of thumb,if your
application has high write concurrency (many connections competing to write to
the same database) and it is time critical,you probably need another database. It
is really a matter of testing your application to know what kind of performance
you can get. We have seen sqlite handle more than 500 transactions per second
for 100 concurrent connections in simple web applications. But your transactions
may differ in the number of records being modified or the number and complexity
of the queries involved. Acceptable concurrency all depends on your particular
application and can be determined empirically only by direct testing. In general,
this is true with any database: you don’t know what kind of performance your
application will get until you do real-world tests.
•Networking(网络). Although sqlite databases can be shared over network file systems,
the latency associated with such file systems can cause performance to suffer.
Worse,bugs in network file system implementations can also make opening and
modifying remote files—sqlite or otherwise—error prone. If the file system’s
locking does not work properly,two clients may be allowed to simultaneously
modify the same database file,which will almost certainly result in database
corruption. It is not that sqlite is incapable of working over a network file system
because of anything in its implementation. Rather,sqlite is at the mercy of the
underlying file system and wire protocol,and those technologies are not always
perfect. For instance,many versions of NFS have a flawed fcntl()
implementation,meaning that locking does not behave as intended. Newer NFS
versions,such are Solaris NFS v4,work just fine and reliably implement the
requisite locking mechanisms needed by sqlite. However,the sqlite developers
have neither the time nor the resources to certify that any given network file
system works flawlessly in all cases.
Again,most of these limitations are intentional,resulting from sqlite’s design. Supporting high
write concurrency,for example,brings with it great deal of complexity,and this runs counter to sqlite’ssimplicity in design. Similarly,being an embedded database,sqlite intentionally does not support
networking. This should come as no surprise. In short,what sqlite can’t do is a direct result of what it
can. It was designed to operate as a modular,simple,compact,and easy-to-use embedded relational
database whose code base is within the reach of the programmers using it. And in many respects,it can
do what many other databases cannot,such as run in embedded environments where actual power
consumption is a limiting factor.
While sqlite’s sql implementation is quite good,there are some things it currently does not
implement. These are as follows:
• Complete trigger support. sqlite supports almost all the standard features for
triggers,including recursive triggers and INSTEAD OF triggers. However,for all
trigger types,sqlite currently requires FOR EACH ROW behavior,where the triggered
action is evaluated for every row affected by the triggering query. ANSI sql 92 also
describes a FOR EACH STATEMENT trigger style,which is not currently supported.
• Complete ALTER TABLE support. Only the RENAME TABLE and ADD COLUMN variants
of the ALTER TABLE command are supported. Other kinds of ALTER TABLE
operations such as DROP COLUMN,ALTER COLUMN,and ADD CONSTRAINT are not
implemented.
• RIGHT and FULL OUTER JOIN. LEFT OUTER JOIN is implemented,but RIGHT
OUTER JOIN and FULL OUTER JOIN are not. Every RIGHT OUTER JOIN has a provably
semantically identical LEFT OUTER JOIN,and vice versa. Any RIGHT OUT JOIN can be
implemented as a LEFT OUTER JOIN by simply reversing the order of the tables and
modifying the join constraint. A FULL OUTER JOIN can be implemented as a
combination of two LEFT OUTER JOIN statements,a UNION,and appropriate NULL
filtering in the WHERE clause.
• Updatable views. Views in sqlite are read-only. You may not execute a DELETE,
INSERT,or UPDATE statement on a view. But you can create a trigger that fires on an
attempt to DELETE,or UPDATE a view and do what you need in the body of
the trigger.
• Windowing functions. One of the new feature sets specified in ANSI sql 99 are
the windowing functions. These provide post-processing analytic functions for
results,such a ranking,rolling averages,lag and lead calculation,and so on.
sqlite currently only targets ANSI sql 92 compliance,so it doesn’t support
windowing functions like RANK(),ROW_NUMBER(),and so on.
• GRANT and REVOKE. Since sqlite reads and writes an ordinary disk file,the only
access permissions that can be applied are the normal file access permissions of
the underlying operating system. GRANT and REVOKE commands in general are
aimed at much higher-end systems where there are multiple users who have
varying access levels to data in the database. In the sqlite model,the application
is the main user and has access to the entire database. Access in this model is
defined at the application level—specifically,what applications have access to the
database file.
In addition to what is listed here,there is a page on the sqlite wiki devoted to reporting
unsupported sql. It is located at www.sqlite.org/cvstrac/wiki?p=Unsupportedsql.
From: The Definitive Guide to sqlite (2nd edition)
原文链接:https://www.f2er.com/sqlite/198438.html