Tomorrow I have to hit some spots with steam to disappear the heat ink that I missed, do laundry, dust my wheelchair, and pack EVERYTHING that isn’t sleep supplies so I can be ready to hit the road Thursday with dragons & bears.
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
✓ Live Streaming✓ Interactive Chat✓ Private Shows✓ HD Quality✓ Free Actions
Free to watch • No registration required • HD streaming
Разговаривали с Андрюхой о детях и о том, как быть родителями, потом поговорили об этом с Хвостом. Он попросил меня вести дневник беременной женщины, чтобы узнать, каково это. По-моему, это замечательная идея. Хоть где-то будут записи о моей беременности. Будет интересно, если мы поженимся в конце июля, а к фестивалю я уже буду беременна :3 конечно, это тогда ещё не будет заметно, но окажется, что дитё побывает со мной на фестивале, даже ещё не родившись :3
Charting against an Akiban deployment using chartio
One of the big advantages of the Akiban Service is very fast SQL against native object data (what I technically call nested tuples).
This weekend we had a chance to get chartio working directly against an Akiban deployment. Because we are not 100% compatible with the postgres protocol there were a few loose ends that needed tightening. A little work by our Mike McMahon combined with a bit of advice from Dave Fowler and his team at chartio, and the beauty of running fast SQL reports against object/JSON data comes to life. Here is a sample chartio dashboard working against the employees ‘default’ space that is deployed with every new account.
To get started login to try.akiban.com and select your favorite deployment:
Then use the credentials to connect chartio to the data:
and off you go creating dashboards to your hearts delight.
Translation: scan the index in DESC order, look up the user row in the table group using AncestorLookup operator, Project the row to output and Limit to 5 rows. Simple.
A more common query is one looking for users with the latest changes:
SELECT * FROM user ORDER BY latest_change DESC LIMIT 5;
Well, that's easy. Put an index on user.latest_change. Done. The execution is about the same:
What if another table was involved? Say, filtering users with a specific memberships level on top of the same query (a user may have several membership levels):
SELECT * FROM user, user_membership WHERE user.uid = user_membership.uid AND user_membership.membership_level = 3 ORDER BY user.latest_change DESC LIMIT 5;
Well, in a relational system I'm a bit stuck.
Option 1:
use an index on user_membership.membership_level. Go to the user_membership row to get the uid. For each uid get the user row and the latest change. Put in a temp table. When done scanning the index sort all the users in the temp table on latest_change. Now bring the latest 5 in DESC order. If there are only 10 users with that membership level it's not too bad. What if there are 10,000 user with that membership level? Scan all 10,000 and sort them to bring back 5. kind of expensive.
There must be something else a relational system can do right?
Yes,
Option 2:
use the index on user.latest_change as before, scan it in descending order, but rather than returning each user, first check that the user has membership 3. If the user has membership level 3 return the row, otherwise, discard it and continue to the next row.
This plan is diametrically opposite to the previous one. It'll be very good for a very common membership level and very bad if it is rare. It eliminates the sort but may have to scan a lot of the users to come up with the 5 it needs.
Win some loss some? Yes, except losing in one million users could hurt for a few seconds each time.
In Akiban Server we can build indexes on table groups, not just single tables:
CREATE INDEX 'GROUP_INDEX_EXAMPLE' ON user_membership (user_membership.membership_level, user.latest_change)
And the execution plan? As simple and efficient as the other queries on a single table above. It scans 5 index values max because it now has a covering index that provides both filtering and sorting:
So this new Index Scan in the line above applies the predicate as a range (membership_level>=3 AND membership_level<=3) asking for the output to be sorted by the latest_change column in DESC order.
A small feature that's highly effective because this is such a common use case.
Query 1 (pure scan) Query 2 (scan and expression evaluation)
Akiban 5.955 sec 8.908 sec
MySQL 11.75 sec 11.89 sec
Details:
Setup: a large USER table with 5 million rows is created. An index on the user location is used for the scan. The index is on an INT location column with a large distribution of values. I made sure that all queries run from memory and run each query multiple times (though not enough for full JIT to take effect).
Queries:
Query 1: without expression evaluation:
select sum(locationID) from USERS;
Query 2: with expression evaluation
select sum(locationID+2) from USERS;
Index def:
KEY `idx_user_locationID` (`locationID`)
The column itself is defined as
`locationID` int(11) DEFAULT NULL
I picked this column because it maps to another table called locations and so would have a relatively large distribution of values, e.g. all possible locIDs and so prefix elision would not fully compress the values. Trying to get the precise size of the index in either MySQL or Akiban is difficult right now, and so we simply estimated the upper boundary. Considering that the Akiban index has a key structured like (`locationID`, hkey) and that each locationID is a long, we would end up with 16 bytes/index entry before compression. After compression I estimate the average width at 10 bytes/index entry, and so at about 5 million entries I estimate the index size to be 50MB.
Another minor point: Because of time constraints, InnoDB had fewer rows loaded into it than Akiban Server (4.9 million compared to 5.7 million for Akiban)
Akiban explain plan for query 1
project([Field(0)]) Aggregation(without GROUP BY: [sumLONG]) project([Field(0)]) IndexScan_Default(Index(USERS.idx_locationID[IndexColumn(locationID)])
+----+-------------+-------------+-------+---------------+------------------+---------+------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------+-------+---------------+------------------+---------+------+---------+-------------+ | 1 | SIMPLE | USERS | index | NULL | idx_locationID | 5 | NULL | 4900000 | Using index | +----+-------------+-------------+-------+---------------+------------------+---------+------+---------+-------------+
Conclusion:
1. The core Akiban advantage for scan (on small width entries) is about 2x.
2. The theoretical maximum bandwidth for memory is over 10GB/sec (link). This means that there is a lot of room to optimize scan, both within a single thread, as well as splitting to multiple reading threads before this bandwidth is saturated.
3. The degradation in Akiban Server processing of query 2, is actually caused by object allocations rather than expression evaluation in the Project operator. [Last minute update: Akiban's Server team identified the root cause and brought the difference between query 1 and query 2 to 0.11sec].
4. As a perspective remember that relational systems where built for disk scans, where the disk max scan rate is at 10s of MB/Sec, so the old methods of scanning works fine and would saturate that limit. We need to significantly optimize this for a memory based world.
Next steps:
1. Repeat the experiment scanning tables of different widths.
2. Run with a visitor pattern where batches of 100 rows are moved from the underlying storage (Akiban Persistit) to the IndexScan operator to estimate the impact this would have.
3. Run with the parallel execution to see how we scale with cores.
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
✓ Live Streaming✓ Interactive Chat✓ Private Shows✓ HD Quality✓ Free Actions
Free to watch • No registration required • HD streaming
Like Akiban, Google’s newest database uses Table-groups - Great minds think alike.
There’s another way to do databases, and it looks like the industry is waking up to the ideas that we’ve been working on for years.
In classic relational systems, objects (or documents) get normalized into multiple physically distinct tables. While normalization is great for modeling it translates to massive inefficiency in both storage and access of distinct tables. It just doesn’t scale.
The core realization we came to, and apparently now Google came to as well, is that rows from related tables that are always retrieved together should be colocated with one another. A customer row should be stored with it’s order rows. An order row should be stored with it’s item rows. When you retrieve this collection of related rows, you will get it in a single read. When you transact on these records it will write to a single location. It scales.
And, this is a “big deal”. Do you know Edgar Codd? He’s the father of relational databases,and 40 years ago he “invented” the use of relational algebra and relational modeling for databases. In the first sentence of his seminal work he opens with:
"Future users of large data banks must be protected from having to know how
the data is organized in the machine (the internal representation)."
Let’s pause and listen. What he’s telling us is that there’s no reason why data has to be physically stored in tables. But, databases are all about tables, right? How could you have SQL without tables?
I’ve always thought that this idea, this insight in Codd’s vision is the missing link between RDBMs and what we have called “NoSQL”. There’s this competition between the two that doesn’t need to exist. NoSQL vendors are running around painting relational databases as the enemy, and just last week I saw a flurry of Tweets proclaiming the beginning of the “post-relational age”. This is premature overreaction. Relational databases have a lot of room to grow. With the right approach we can get the best of both worlds: Document like access to table-groups alongside seriously fast SQL, and we’re just getting started. SQL is just a language and scapegoat. We’d rather solve the fundamental problem related to physical data storage and processing.
While Google has been busy migrating one of their most critical systems, we’ve been helping our customers do the same. These are customers that were hitting the same performance and scalability bottlenecks that drove the development of F1. Google’s solution is for a system that runs on Google scale with massive data centers. The solution Akiban is building is for any scale. We think that the central idea of table-groups can benefit all applications (even if they run in fewer than 11 data centers).
So what do table-groups give us?
Simpler schema: A relational schema goes from hundreds or thousands of tables to a few main table-groups
Merge documents and SQL: A table group is a definition for an object or document
Super high performance: Queries are fast. In fact, table-groups replace Fact Tables because joins are eliminated (like Fact tables) but without the data redundancy