電視節目上表演從 Amazon Echo 買東西...

然後觀眾家裡的 Amazon Echo 就跟著買了 XDDD:「TV anchor says live on-air 'Alexa, order me a dollhouse' – guess what happens next」。

A San Diego TV station sparked complaints this week – after an on-air report about a girl who ordered a dollhouse via her parents' Amazon Echo caused Echoes in viewers' homes to also attempt to order dollhouses.

MySQL 8.0 將會實作「真正的」Descending Indexes

在「MySQL 8.0 Labs – Descending Indexes in MySQL」這邊看到 MySQL 打算在 8.0 時實作出真正的 Descending Indexes。在 5.7 以及之前的版本,可以從「14.1.14 CREATE INDEX Syntax」看到這個參數是~假~的~XDDD

An index_col_name specification can end with ASC or DESC. These keywords are permitted for future extensions for specifying ascending or descending index value storage. Currently, they are parsed but ignored; index values are always stored in ascending order.

所以當 8.0 建立了 a_desc_b_asc (a DESC, b ASC) 這樣的 index,可以看到對於不同 ORDER BY 時效能的差異:(一千萬筆資料)

有些變快可以理解,但有些結果不太清楚造成的原因...

Anyway,對於變慢的兩個 query,他提了一個不算解法的解法,就是加上對應的 index XDDD:

If user wants to avoid filesorts for Query 5 and Query 6, he/she can alter the table to add a key (a ASC, b ASC) . Further to this, if the user wants to avoid backward index scans too, he/she can add both ( a ASC, b DESC) and (a DESC, b DESC).

這樣就會變快,但寫入的 overhead 會增加啊... XD

但不管怎樣,總算是把這個功能生出來了...

Python 3.6 對 Dict 的改善

Python 3 的 Dict 將會有重大的改變:「[Python-Dev] Python 3.6 dict becomes compact and gets a private version; and keywords become ordered」。

在 3.5 時:

Python 3.5.1 (default, Jun 20 2016, 14:48:22)
>>> def func(**kw): print(kw.keys())
...
>>> func(a=1, b=2, c=3, d=4, e=5)
dict_keys(['c', 'd', 'e', 'b', 'a'])   # random order

對上目前還在開發的 3.6:

Python 3.6.0a4+ (default:d43f819caea7, Sep  8 2016, 13:05:34)
>>> def func(**kw): print(kw.keys())
...
>>> func(a=1, b=2, c=3, d=4, e=5)
dict_keys(['a', 'b', 'c', 'd', 'e'])   # expected order

在「Compact and ordered dict」這邊可以看到記憶體的使用量降低:

It seems like the memory usage is between 20% and 25% smaller. Great job!

Memory usage, Python 3.5 => Python 3.6 on Linux x86_64:

./python -c 'import sys; print(sys.getsizeof({str(i):i for i in range(10)}))'

* 10 items: 480 B => 384 B (-20%)
* 100 items: 6240 B => 4720 B (-24%)
* 1000 items: 49248 B => 36984 B (-25%)

Note: the size is the the size of the container itself, not of keys nor values.

不過效能上似乎慢了一些:

3% slowdown in microbench is not surprising.
Compact dict introduces one additional indirection.

Instead, I've added freelist for most compact PyDictKeys.
So I think overall performance is almost same to before compact dict.

不過也有人提到應該拿 3.5 + patch 測,而不是直接拿 3.6 測:

There are a lot of other changes in interpreter core between 3.5 and 3.5 (such as new bytecode and optimized function calls). Could you compare the performance between the version just before adding new dict implementation and the version just after this?

看起來後續還在進行中...

超強的萬用信用卡 Plastc 的原型工程版出來了...

剛剛收到 Plastc 通知信說他們更新消息,有 prototype 的示範影片可以看了:「Plastc Prototype in Action」。

先看他們之前的宣傳影片:

而這是工程版的 prototype 示範影片:

比起以前嘴砲來的可信度高多了,雖然還是很有可能沒出貨...

Pre-order (預購) 是 USD$155,而寄到台灣要多加 USD$10 的費用,所以是 USD$165。我就當跟當初買挖礦機的風險一樣好了,沒預期會拿到東西。

如果你有興趣,而且也願意承擔最後有可能沒出貨的風險,可以用我的連結購買:https://share.plastc.com/x/NO0S0J,我跟你都會拿到 USD$20 的好處:

They’ll receive a $20 discount when they pre-order Plastc, and you’ll receive a $20 Amazon gift card with your Plastc Card.

Update:補充其他人對這個產品的反面看法。

MySQL 在處理 GROUP BY 時選擇 index 的效率問題

Percona 的「Speed up GROUP BY queries with subselects in MySQL」這篇講了 MySQL 在處理 GROUP BY 的效率問題。

舉原文的例子,也就是這樣的 SQL query:(我把 command 都改成大寫,其他部份都改成小寫)

SELECT a.name, SUM(a.count) a_sum, AVG(a.position) a_avg, b.col1, c.col2, d.col3
FROM
a JOIN
b ON (a.bid = b.id) JOIN
c ON (a.cid = c.id) JOIN
d ON (a.did = d.id) GROUP BY a.name, b.id, c.id, d.id

其中 TABLE a 有 1.3M rows,而 b、c、d 都只有 5 rows。

由於會需要計算每組 (a.name, b.id, c.id, d.id)SUM(a.count)AVG(a.position),不可避免的是需要對 TABLE a 完整的掃一次。所以效能的改善會在於可以減少 temporily table 的大小。

上面這組 SQL query 會先 JOIN 完後再 GROUP BY,也就是會全部先展開後再 GROUP BY

由於 GROUP BY 所使用到的條件都可以在 TABLE a 裡面找到,所以這邊可以先 GROUP BY 後再 JOIN,降低 temporily table 的大小:

SELECT a.name, a_sum, a_avg, b.col1, c.col2, d.col3
FROM
(SELECT name, SUM(count) a_sum, AVG(position) a_avg, bid, cid, did
 FROM a
 GROUP BY name, bid, cid, did) a JOIN
 b ON (a.bid = b.id) JOIN
 c ON (a.cid = c.id) JOIN
 d ON (a.did = d.id)

原文測試出來的結果是從 2.3 秒降到 1.8 秒:

The first query took 2.3 sec avg and the optimized query took 1.8 sec average, half a second faster.

另外一個改善是再加上 covering index:

ALTER TABLE a ADD INDEX (name, bid, cid, did, count, position);

加上去之後,原來的 query 變成 1.9 秒,而改善後的變成 0.7 秒,速度快很多。不過這是 trade-off,多了這個 index 在寫入時的成本也會增加。

AWS ELB 加強安全性...

AWS ELB 加強對 SSL 安全性的功能:「Elastic Load Balancing – Perfect Forward Secrecy and Other Security Enhancements」。

第一個是支援 PFS (Perfect Forward Secrecy),愈大多數的實做相同,是使用 ECDH

第二個是 Server Order Preference,由 server 這邊決定最終的 cipher。

最重要的是第三個,也就是「懶人包」。推出新的 security policy ELBSecurityPolicy-2014-01,把上面兩個都設進去了。

這次的升級是對安全性的提昇...

Percona 的「Advanced MySQL Query Tuning」...

先前在「Percona 要講進階的 MySQL Query Tuning...」提到 Percona 所辦的 Webniar「Advanced MySQL Query Tuning」的投影片放出來了:「Advanced MySQL Query Tuning」。

這份內容需要 B+Tree 操作的背景知識才能了解。裡面講了很多 GROUP BYORDER BY 混用時的 index 技巧,以及各種奇怪的 hack 方式。

內容很有用,能吸收多少就看個人造化 :p